Merge "Removed spoken descriptions for characters supported by TTS or TalkBack."
diff --git a/java/res/values-ar/donottranslate-more-keys.xml b/java/res/values-ar/donottranslate-more-keys.xml
index 6a14a3c..9a7a026 100644
--- a/java/res/values-ar/donottranslate-more-keys.xml
+++ b/java/res/values-ar/donottranslate-more-keys.xml
@@ -102,8 +102,43 @@
     <string name="more_keys_for_bullet">♪</string>
     <!-- \u066d: ARABIC FIVE POINTED STAR -->
     <string name="more_keys_for_star">★,\u066d</string>
-    <!-- \ufd3e: ORNATE LEFT PARENTHESIS -->
-    <string name="more_keys_for_left_parenthesis">[,{,&lt;,\ufd3e</string>
-    <!-- \ufd3f: ORNATE RIGHT PARENTHESIS -->
-    <string name="more_keys_for_right_parenthesis">],},&gt;,\ufd3f</string>
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <string name="output_text_for_left_parenthesis">)</string>
+    <string name="output_text_for_right_parenthesis">(</string>
+    <!-- \ufd3e: ORNATE LEFT PARENTHESIS
+         \ufd3f: ORNATE RIGHT PARENTHESIS -->
+    <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;,\ufd3e|\ufd3f</string>
+    <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;,\ufd3f|\ufd3e</string>
+    <string name="output_text_for_less_than">&gt;</string>
+    <string name="output_text_for_greater_than">&lt;</string>
+    <!-- \u2264: LESS-THAN OR EQUAL TO
+         \u2265: GREATER-THAN EQUAL TO
+         \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+         \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+         The following characters don't need BIDI mirroring.
+         \u2018: LEFT SINGLE QUOTATION MARK
+         \u2019: RIGHT SINGLE QUOTATION MARK
+         \u201a: SINGLE LOW-9 QUOTATION MARK
+         \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+         \u201c: LEFT DOUBLE QUOTATION MARK
+         \u201d: RIGHT DOUBLE QUOTATION MARK
+         \u201e: DOUBLE LOW-9 QUOTATION MARK
+         \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+    <string name="more_keys_for_less_than">\u2264|\u2265,\u00ab|\u00bb,\u2039|\u203a</string>
+    <string name="more_keys_for_greater_than">\u2265|\u2264,\u00bb|\u00ab,\u203a|\u2039</string>
+    <string name="output_text_for_left_square_bracket">]</string>
+    <string name="output_text_for_right_square_bracket">[</string>
+    <string name="output_text_for_left_curly_bracket">}</string>
+    <string name="output_text_for_right_curly_bracket">{</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+    <string name="more_keys_for_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+    <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab,\u2019,\u201a,\u2018,\u201b</string>
 </resources>
diff --git a/java/res/xml-ar/kbd_symbols_shift.xml b/java/res/values-ar/donottranslate.xml
similarity index 60%
copy from java/res/xml-ar/kbd_symbols_shift.xml
copy to java/res/values-ar/donottranslate.xml
index 820b425..a9aad4e 100644
--- a/java/res/xml-ar/kbd_symbols_shift.xml
+++ b/java/res/values-ar/donottranslate.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -17,11 +17,9 @@
 ** limitations under the License.
 */
 -->
-
-<Keyboard
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
->
-    <include
-        latin:keyboardLayout="@xml/rows_symbols_shift" />
-</Keyboard>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values-iw/donottranslate-more-keys.xml b/java/res/values-iw/donottranslate-more-keys.xml
index 829486f..6fc3360 100644
--- a/java/res/values-iw/donottranslate-more-keys.xml
+++ b/java/res/values-iw/donottranslate-more-keys.xml
@@ -20,4 +20,41 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="more_keys_for_star">★</string>
     <string name="more_keys_for_plus">±,﬩</string>
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <string name="output_text_for_left_parenthesis">)</string>
+    <string name="output_text_for_right_parenthesis">(</string>
+    <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;</string>
+    <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;</string>
+    <string name="output_text_for_less_than">&gt;</string>
+    <string name="output_text_for_greater_than">&lt;</string>
+    <!-- \u2264: LESS-THAN OR EQUAL TO
+         \u2265: GREATER-THAN EQUAL TO
+         \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+         \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+         The following characters don't need BIDI mirroring.
+         \u2018: LEFT SINGLE QUOTATION MARK
+         \u2019: RIGHT SINGLE QUOTATION MARK
+         \u201a: SINGLE LOW-9 QUOTATION MARK
+         \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+         \u201c: LEFT DOUBLE QUOTATION MARK
+         \u201d: RIGHT DOUBLE QUOTATION MARK
+         \u201e: DOUBLE LOW-9 QUOTATION MARK
+         \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+    <string name="more_keys_for_less_than">\u2264|\u2265,\u00ab|\u00bb,\u2039|\u203a</string>
+    <string name="more_keys_for_greater_than">\u2265|\u2264,\u00bb|\u00ab,\u203a|\u2039</string>
+    <string name="output_text_for_left_square_bracket">]</string>
+    <string name="output_text_for_right_square_bracket">[</string>
+    <string name="output_text_for_left_curly_bracket">}</string>
+    <string name="output_text_for_right_curly_bracket">{</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+    <string name="more_keys_for_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+    <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab,\u2019,\u201a,\u2018,\u201b</string>
 </resources>
diff --git a/java/res/xml-iw/kbd_symbols_shift.xml b/java/res/values-iw/donottranslate.xml
similarity index 60%
rename from java/res/xml-iw/kbd_symbols_shift.xml
rename to java/res/values-iw/donottranslate.xml
index 820b425..a9aad4e 100644
--- a/java/res/xml-iw/kbd_symbols_shift.xml
+++ b/java/res/values-iw/donottranslate.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -17,11 +17,9 @@
 ** limitations under the License.
 */
 -->
-
-<Keyboard
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
->
-    <include
-        latin:keyboardLayout="@xml/rows_symbols_shift" />
-</Keyboard>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index a5bf6f6..dd2206d 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -202,8 +202,6 @@
         <attr name="verticalGap" format="dimension|fraction" />
         <!-- More keys keyboard layout template -->
         <attr name="moreKeysTemplate" format="reference" />
-        <!-- True if the keyboard is Right-To-Left -->
-        <attr name="isRtlKeyboard" format="boolean" />
         <!-- Icon set for key top and key preview. -->
         <attr name="iconShiftKey" format="reference" />
         <attr name="iconDeleteKey" format="reference" />
@@ -249,6 +247,7 @@
             <flag name="isRepeatable" value="0x01" />
             <flag name="noKeyPreview" value="0x02" />
             <flag name="altCodeWhileTyping" value="0x04" />
+            <flag name="enableLongPress" value="0x08" />
         </attr>
         <!-- The string of characters to output when this key is pressed. -->
         <attr name="keyOutputText" format="string" />
@@ -341,7 +340,7 @@
             <enum name="symbols" value="5" />
             <enum name="symbolsShifted" value="6"  />
             <enum name="phone" value="7"  />
-            <enum name="phoneShifted" value="8"  />
+            <enum name="phoneSymbols" value="8"  />
             <enum name="number" value="9"  />
         </attr>
         <!-- This should be aligned with KeyboardId.MODE_* -->
@@ -403,7 +402,7 @@
             <enum name="symbols" value="5" />
             <enum name="symbolsShifted" value="6"  />
             <enum name="phone" value="7"  />
-            <enum name="phoneShifted" value="8"  />
+            <enum name="phoneSymbols" value="8"  />
             <enum name="number" value="9"  />
         </attr>
         <attr name="elementKeyboard" format="reference"/>
diff --git a/java/res/values/donottranslate-more-keys.xml b/java/res/values/donottranslate-more-keys.xml
index 07f4bf3..07e711a 100644
--- a/java/res/values/donottranslate-more-keys.xml
+++ b/java/res/values/donottranslate-more-keys.xml
@@ -112,6 +112,43 @@
     <string name="more_keys_for_bullet">♪,♥,♠,♦,♣</string>
     <string name="more_keys_for_star">†,‡,★</string>
     <string name="more_keys_for_plus">±</string>
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <string name="output_text_for_left_parenthesis">(</string>
+    <string name="output_text_for_right_parenthesis">)</string>
     <string name="more_keys_for_left_parenthesis">[,{,&lt;</string>
     <string name="more_keys_for_right_parenthesis">],},&gt;</string>
+    <string name="output_text_for_less_than">&lt;</string>
+    <string name="output_text_for_greater_than">&gt;</string>
+    <!-- \u2264: LESS-THAN OR EQUAL TO
+         \u2265: GREATER-THAN EQUAL TO
+         \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+         \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+         \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+         The following characters don't need BIDI mirroring.
+         \u2018: LEFT SINGLE QUOTATION MARK
+         \u2019: RIGHT SINGLE QUOTATION MARK
+         \u201a: SINGLE LOW-9 QUOTATION MARK
+         \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+         \u201c: LEFT DOUBLE QUOTATION MARK
+         \u201d: RIGHT DOUBLE QUOTATION MARK
+         \u201e: DOUBLE LOW-9 QUOTATION MARK
+         \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+    <string name="more_keys_for_less_than">\u2264,\u00ab,\u2039</string>
+    <string name="more_keys_for_greater_than">\u2265,\u00bb,\u203a</string>
+    <string name="output_text_for_left_square_bracket">[</string>
+    <string name="output_text_for_right_square_bracket">]</string>
+    <string name="output_text_for_left_curly_bracket">{</string>
+    <string name="output_text_for_right_curly_bracket">}</string>
+    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+    <string name="more_keys_for_single_quote">\u2019,\u201a,\u2018,\u201b</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+    <string name="more_keys_for_double_quote">\u201d,\u00ab,\u201c,\u00bb</string>
+    <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+    <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+    <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab,\u201c,\u00bb,\u2019,\u201a,\u2018,\u201b</string>
 </resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 8bd25c0..cd5e3d8 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -19,7 +19,7 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations">!?,:;\u0022()\u0027-/@_</string>
+    <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(,),\u0027,-,/,@,_</string>
     <!-- Symbols that should be swapped with a magic space -->
     <string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
     <!-- Symbols that should strip a magic space -->
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
index b3f71d2..2a91a3d 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -25,7 +25,6 @@
     <integer name="key_space">32</integer>
     <integer name="key_shift">-1</integer>
     <integer name="key_switch_alpha_symbol">-2</integer>
-    <integer name="key_capslock">-3</integer>
     <integer name="key_output_text">-4</integer>
     <integer name="key_delete">-5</integer>
     <integer name="key_settings">-6</integer>
diff --git a/java/res/xml-ar/kbd_symbols.xml b/java/res/xml-ar/kbd_symbols.xml
deleted file mode 100644
index c1905b8..0000000
--- a/java/res/xml-ar/kbd_symbols.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
->
-    <include
-        latin:keyboardLayout="@xml/rows_symbols" />
-</Keyboard>
diff --git a/java/res/xml-ar/keyboard_set.xml b/java/res/xml-ar/keyboard_set.xml
index a8aac16..7b70f63 100644
--- a/java/res/xml-ar/keyboard_set.xml
+++ b/java/res/xml-ar/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-be/keyboard_set.xml b/java/res/xml-be/keyboard_set.xml
index c8ee9c1..042264a 100644
--- a/java/res/xml-be/keyboard_set.xml
+++ b/java/res/xml-be/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-bg/keyboard_set.xml b/java/res/xml-bg/keyboard_set.xml
index 5a75964..49914d5 100644
--- a/java/res/xml-bg/keyboard_set.xml
+++ b/java/res/xml-bg/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-cs/keyboard_set.xml b/java/res/xml-cs/keyboard_set.xml
index 6b476df..b453516 100644
--- a/java/res/xml-cs/keyboard_set.xml
+++ b/java/res/xml-cs/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-da/keyboard_set.xml b/java/res/xml-da/keyboard_set.xml
index cf930dd..cf01ae6 100644
--- a/java/res/xml-da/keyboard_set.xml
+++ b/java/res/xml-da/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-de-rZZ/keyboard_set.xml b/java/res/xml-de-rZZ/keyboard_set.xml
index 585dc3d..635884d 100644
--- a/java/res/xml-de-rZZ/keyboard_set.xml
+++ b/java/res/xml-de-rZZ/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-de/keyboard_set.xml b/java/res/xml-de/keyboard_set.xml
index 059174c..485e63f 100644
--- a/java/res/xml-de/keyboard_set.xml
+++ b/java/res/xml-de/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-es/keyboard_set.xml b/java/res/xml-es/keyboard_set.xml
index ec40a5a..2944a83 100644
--- a/java/res/xml-es/keyboard_set.xml
+++ b/java/res/xml-es/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-et/keyboard_set.xml b/java/res/xml-et/keyboard_set.xml
index 80a9d8f..1c23db3 100644
--- a/java/res/xml-et/keyboard_set.xml
+++ b/java/res/xml-et/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fi/keyboard_set.xml b/java/res/xml-fi/keyboard_set.xml
index cf95b5e..e8e4e7d 100644
--- a/java/res/xml-fi/keyboard_set.xml
+++ b/java/res/xml-fi/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr-rCA/keyboard_set.xml b/java/res/xml-fr-rCA/keyboard_set.xml
index 856363e..ea6ac8f 100644
--- a/java/res/xml-fr-rCA/keyboard_set.xml
+++ b/java/res/xml-fr-rCA/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr-rCH/keyboard_set.xml b/java/res/xml-fr-rCH/keyboard_set.xml
index 778754c..751900b 100644
--- a/java/res/xml-fr-rCH/keyboard_set.xml
+++ b/java/res/xml-fr-rCH/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr/keyboard_set.xml b/java/res/xml-fr/keyboard_set.xml
index ae911af..42a20e5 100644
--- a/java/res/xml-fr/keyboard_set.xml
+++ b/java/res/xml-fr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-hr/keyboard_set.xml b/java/res/xml-hr/keyboard_set.xml
index 4bd81d0..e17aefd 100644
--- a/java/res/xml-hr/keyboard_set.xml
+++ b/java/res/xml-hr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-hu/keyboard_set.xml b/java/res/xml-hu/keyboard_set.xml
index 9ed1d94..0f6e575 100644
--- a/java/res/xml-hu/keyboard_set.xml
+++ b/java/res/xml-hu/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-iw/kbd_symbols.xml b/java/res/xml-iw/kbd_symbols.xml
deleted file mode 100644
index c1905b8..0000000
--- a/java/res/xml-iw/kbd_symbols.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
->
-    <include
-        latin:keyboardLayout="@xml/rows_symbols" />
-</Keyboard>
diff --git a/java/res/xml-iw/keyboard_set.xml b/java/res/xml-iw/keyboard_set.xml
index c16a6d7..501ba96 100644
--- a/java/res/xml-iw/keyboard_set.xml
+++ b/java/res/xml-iw/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ky/keyboard_set.xml b/java/res/xml-ky/keyboard_set.xml
index 1bb8926..abd5f16 100644
--- a/java/res/xml-ky/keyboard_set.xml
+++ b/java/res/xml-ky/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml-land/kbd_phone_symbols.xml
similarity index 93%
rename from java/res/xml-land/kbd_phone_shift.xml
rename to java/res/xml-land/kbd_phone_symbols.xml
index f456a17..41ba6cf 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml-land/kbd_phone_symbols.xml
@@ -24,5 +24,5 @@
     latin:keyWidth="26.67%p"
 >
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone_symbols" />
 </Keyboard>
diff --git a/java/res/xml-nb/keyboard_set.xml b/java/res/xml-nb/keyboard_set.xml
index 1a36de4..d146beb 100644
--- a/java/res/xml-nb/keyboard_set.xml
+++ b/java/res/xml-nb/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-pl/keyboard_set.xml b/java/res/xml-pl/keyboard_set.xml
index 39ee777..6d27379 100644
--- a/java/res/xml-pl/keyboard_set.xml
+++ b/java/res/xml-pl/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-pt/keyboard_set.xml b/java/res/xml-pt/keyboard_set.xml
index bd19761..65f9634 100644
--- a/java/res/xml-pt/keyboard_set.xml
+++ b/java/res/xml-pt/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ro/keyboard_set.xml b/java/res/xml-ro/keyboard_set.xml
index 75ca682..6c34966 100644
--- a/java/res/xml-ro/keyboard_set.xml
+++ b/java/res/xml-ro/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ru/keyboard_set.xml b/java/res/xml-ru/keyboard_set.xml
index 8d4d277..b6a3568 100644
--- a/java/res/xml-ru/keyboard_set.xml
+++ b/java/res/xml-ru/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sk/keyboard_set.xml b/java/res/xml-sk/keyboard_set.xml
index b73c446..b283d96 100644
--- a/java/res/xml-sk/keyboard_set.xml
+++ b/java/res/xml-sk/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sl/keyboard_set.xml b/java/res/xml-sl/keyboard_set.xml
index b2378e2..dbb2782 100644
--- a/java/res/xml-sl/keyboard_set.xml
+++ b/java/res/xml-sl/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sr/keyboard_set.xml b/java/res/xml-sr/keyboard_set.xml
index 729136f..15471db 100644
--- a/java/res/xml-sr/keyboard_set.xml
+++ b/java/res/xml-sr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sv/keyboard_set.xml b/java/res/xml-sv/keyboard_set.xml
index 3d366a4..e5184d3 100644
--- a/java/res/xml-sv/keyboard_set.xml
+++ b/java/res/xml-sv/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sw600dp-land/kbd_phone_shift.xml b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw600dp-land/kbd_phone_shift.xml
rename to java/res/xml-sw600dp-land/kbd_phone_symbols.xml
index ba83792..e3f56bc 100644
--- a/java/res/xml-sw600dp-land/kbd_phone_shift.xml
+++ b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
@@ -23,6 +23,7 @@
     latin:keyboardHorizontalEdgesPadding="10%p"
     latin:keyWidth="15.00%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_phone_shift.xml b/java/res/xml-sw600dp/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw600dp/kbd_phone_shift.xml
rename to java/res/xml-sw600dp/kbd_phone_symbols.xml
index e722545..9faeaf4 100644
--- a/java/res/xml-sw600dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw600dp/kbd_phone_symbols.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyWidth="15.00%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw600dp/rows_azerty.xml b/java/res/xml-sw600dp/rows_azerty.xml
index c29d291..aabe6b0 100644
--- a/java/res/xml-sw600dp/rows_azerty.xml
+++ b/java/res/xml-sw600dp/rows_azerty.xml
@@ -116,7 +116,10 @@
             latin:keyLabel="n"
             latin:moreKeys="@string/more_keys_for_n" />
         <Key
-            latin:keyLabel="\'" />
+            latin:keyLabel="\'"
+            latin:keyHintLabel=":"
+            latin:moreKeys=":"
+            latin:keyStyle="hasShiftedLetterHintStyle" />
         <include
             latin:keyboardLayout="@xml/keys_comma_period" />
         <include
diff --git a/java/res/xml-sw600dp/rows_phone.xml b/java/res/xml-sw600dp/rows_phone.xml
index 1bad7ca..fe85119 100644
--- a/java/res/xml-sw600dp/rows_phone.xml
+++ b/java/res/xml-sw600dp/rows_phone.xml
@@ -28,7 +28,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="17.375%p" />
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel="-"
             latin:keyStyle="numKeyStyle"
@@ -38,6 +38,9 @@
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
         <Key
+            latin:keyStyle="numPauseKeyStyle"
+            latin:keyWidth="9.25%p" />
+        <Key
             latin:keyStyle="num1KeyStyle"
             latin:keyXPos="42.25%p" />
         <Key
@@ -52,7 +55,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="17.375%p" />
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel=","
             latin:keyStyle="numKeyStyle"
@@ -62,6 +65,9 @@
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
         <Key
+            latin:keyStyle="numWaitKeyStyle"
+            latin:keyWidth="9.25%p" />
+        <Key
             latin:keyStyle="num4KeyStyle"
             latin:keyXPos="42.25%p" />
         <Key
@@ -74,19 +80,23 @@
             latin:keyWidth="fillRight" />
     </Row>
     <Row>
-        <Key
-            latin:keyStyle="toMoreSymbolKeyStyle"
-            latin:keyWidth="11.0%p" />
+        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+        <Spacer
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel="("
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="17.375%p"
-            latin:keyWidth="9.25%p" />
+            latin:keyWidth="9.25%p"
+            latin:keyXPos="12.75%p" />
         <Key
             latin:keyLabel=")"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
         <Key
+            latin:keyLabel="N"
+            latin:keyStyle="numKeyStyle"
+            latin:keyWidth="9.25%p" />
+        <Key
             latin:keyStyle="num7KeyStyle"
             latin:keyXPos="42.25%p" />
         <Key
@@ -96,15 +106,15 @@
         <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
         <Spacer
             latin:keyWidth="0%p" />
-        </Row>
+    </Row>
     <Row>
         <Key
             latin:keyStyle="numTabKeyStyle"
             latin:keyWidth="11.00%p" />
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyWidth="18.50%p"
-            latin:keyXPos="17.375%p" />
+            latin:keyWidth="27.75%p"
+            latin:keyXPos="12.75%p" />
         <Key
             latin:keyStyle="numStarKeyStyle"
             latin:keyXPos="42.25%p" />
diff --git a/java/res/xml-sw600dp/rows_phone_shift.xml b/java/res/xml-sw600dp/rows_phone_shift.xml
deleted file mode 100644
index c2f00fe..0000000
--- a/java/res/xml-sw600dp/rows_phone_shift.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
-    <include
-        latin:keyboardLayout="@xml/key_styles_common" />
-    <include
-        latin:keyboardLayout="@xml/key_styles_number" />
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="12.75%p" />
-        <Key
-            latin:keyLabel="-"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="+"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="numPauseKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num1KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num2KeyStyle" />
-        <Key
-            latin:keyStyle="num3KeyStyle" />
-        <Key
-            latin:keyStyle="deleteKeyStyle"
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="12.75%p" />
-        <Key
-            latin:keyLabel=","
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="."
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="numWaitKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num4KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num5KeyStyle" />
-        <Key
-            latin:keyStyle="num6KeyStyle" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="backFromMoreSymbolKeyStyle"
-            latin:keyWidth="11.00%p" />
-        <Key
-            latin:keyLabel="("
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p"
-            latin:keyXPos="12.75%p" />
-        <Key
-            latin:keyLabel=")"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="N"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num7KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num8KeyStyle" />
-        <Key
-            latin:keyStyle="num9KeyStyle" />
-        <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-        <Spacer
-            latin:keyWidth="0%p" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="numTabKeyStyle"
-            latin:keyWidth="11.00%p" />
-        <Key
-            latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyWidth="27.75%p"
-            latin:keyXPos="12.75%p" />
-        <Key
-            latin:keyStyle="numStarKeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num0KeyStyle" />
-        <Key
-            latin:keyLabel="#"
-            latin:keyStyle="numKeyStyle" />
-        <Spacer
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="0%p" />
-        <include
-            latin:keyboardLayout="@xml/key_f2" />
-    </Row>
-</merge>
diff --git a/java/res/xml-sw600dp/rows_symbols.xml b/java/res/xml-sw600dp/rows_symbols.xml
index 701c354..c2dfe2f 100644
--- a/java/res/xml-sw600dp/rows_symbols.xml
+++ b/java/res/xml-sw600dp/rows_symbols.xml
@@ -95,12 +95,8 @@
         <Key
             latin:keyLabel="+"
             latin:moreKeys="@string/more_keys_for_plus" />
-        <Key
-            latin:keyLabel="("
-            latin:moreKeys="[,{,&lt;" />
-        <Key
-            latin:keyLabel=")"
-            latin:moreKeys="],},&gt;" />
+        <include
+            latin:keyboardLayout="@xml/keys_parentheses" />
         <Key
             latin:keyStyle="returnKeyStyle"
             latin:keyXPos="-14.6%p"
@@ -112,12 +108,8 @@
         <Key
             latin:keyStyle="toMoreSymbolKeyStyle"
             latin:keyWidth="10.0%p" />
-        <Key
-            latin:keyLabel="&lt;"
-            latin:moreKeys="≤,«,‹" />
-        <Key
-            latin:keyLabel="&gt;"
-            latin:moreKeys="≥,»,›" />
+        <include
+            latin:keyboardLayout="@xml/keys_less_greater" />
         <Key
             latin:keyLabel="="
             latin:moreKeys="≠,≈" />
@@ -126,8 +118,7 @@
                 latin:mode="url"
             >
                 <Key
-                    latin:keyLabel="\'"
-                    latin:moreKeys="‘,’,‚,‛" />
+                    latin:keyLabel="\'" />
             </case>
             <default>
                 <Key
@@ -166,11 +157,10 @@
             latin:keyStyle="spaceKeyStyle"
             latin:keyXPos="30.750%p"
             latin:keyWidth="39.750%p" />
-        <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
-        <!-- latin:moreKeys="“,”,„,‟,«,»,‘,’,‚,‛" -->
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="“,”,«,»,‘,’,‚,‛" />
+            latin:moreKeys="@string/more_keys_for_tablet_double_quote"
+            latin:maxMoreKeysColumn="4" />
         <Key
             latin:keyLabel="_" />
         <Spacer
diff --git a/java/res/xml-sw600dp/rows_symbols_shift.xml b/java/res/xml-sw600dp/rows_symbols_shift.xml
index d3531dd..6a640c0 100644
--- a/java/res/xml-sw600dp/rows_symbols_shift.xml
+++ b/java/res/xml-sw600dp/rows_symbols_shift.xml
@@ -77,10 +77,8 @@
         <Key
             latin:keyLabel="±"
             latin:moreKeys="∞" />
-        <Key
-            latin:keyLabel="{" />
-        <Key
-            latin:keyLabel="}" />
+        <include
+            latin:keyboardLayout="@xml/keys_curly_brackets" />
         <Key
             latin:keyStyle="returnKeyStyle"
             latin:keyXPos="-14.6%p"
@@ -102,10 +100,8 @@
             latin:keyLabel="™" />
         <Key
             latin:keyLabel="℅" />
-        <Key
-            latin:keyLabel="[" />
-        <Key
-            latin:keyLabel="]" />
+        <include
+            latin:keyboardLayout="@xml/keys_square_brackets" />
         <Key
             latin:keyLabel="¡" />
         <Key
diff --git a/java/res/xml-sw768dp-land/kbd_phone_shift.xml b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw768dp-land/kbd_phone_shift.xml
rename to java/res/xml-sw768dp-land/kbd_phone_symbols.xml
index 4ef8e96..641464d 100644
--- a/java/res/xml-sw768dp-land/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
@@ -23,6 +23,7 @@
     latin:keyboardHorizontalEdgesPadding="10%p"
     latin:keyWidth="13.250%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone_shift.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw768dp/kbd_phone_shift.xml
rename to java/res/xml-sw768dp/kbd_phone_symbols.xml
index a56afcc..e1a359e 100644
--- a/java/res/xml-sw768dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyWidth="13.250%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw768dp/rows_azerty.xml b/java/res/xml-sw768dp/rows_azerty.xml
index 886ebec..b9ef898 100644
--- a/java/res/xml-sw768dp/rows_azerty.xml
+++ b/java/res/xml-sw768dp/rows_azerty.xml
@@ -124,9 +124,9 @@
             latin:moreKeys="@string/more_keys_for_n" />
         <Key
             latin:keyLabel="\'"
-            latin:keyLabelFlags="hasShiftedLetterHint"
             latin:keyHintLabel=":"
-            latin:moreKeys=":" />
+            latin:moreKeys=":"
+            latin:keyStyle="hasShiftedLetterHintStyle" />
         <include
             latin:keyboardLayout="@xml/keys_comma_period" />
         <Key
diff --git a/java/res/xml-sw768dp/rows_phone.xml b/java/res/xml-sw768dp/rows_phone.xml
index da90895..789c02c 100644
--- a/java/res/xml-sw768dp/rows_phone.xml
+++ b/java/res/xml-sw768dp/rows_phone.xml
@@ -33,13 +33,16 @@
         <Key
             latin:keyLabel="-"
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="20.400%p"
+            latin:keyXPos="13.829%p"
             latin:keyWidth="8.047%p" />
         <Key
             latin:keyLabel="+"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
         <Key
+            latin:keyStyle="numPauseKeyStyle"
+            latin:keyWidth="8.047%p" />
+        <Key
             latin:keyStyle="num1KeyStyle"
             latin:keyXPos="43.125%p" />
         <Key
@@ -52,19 +55,22 @@
             latin:keyWidth="fillRight" />
     </Row>
     <Row>
-        <Key
-            latin:keyStyle="toMoreSymbolKeyStyle"
-            latin:keyWidth="11.172%p" />
+        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+        <Spacer
+            latin:keyWidth="13.829%p" />
         <Key
             latin:keyLabel=","
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="20.400%p"
+            latin:keyXPos="13.829%p"
             latin:keyWidth="8.047%p" />
         <Key
             latin:keyLabel="."
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
         <Key
+            latin:keyStyle="numWaitKeyStyle"
+            latin:keyWidth="8.047%p" />
+        <Key
             latin:keyStyle="num4KeyStyle"
             latin:keyXPos="43.125%p" />
         <Key
@@ -79,7 +85,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="20.400%p" />
+            latin:keyWidth="13.829%p" />
         <Key
             latin:keyLabel="("
             latin:keyStyle="numKeyStyle"
@@ -89,6 +95,10 @@
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
         <Key
+            latin:keyLabel="N"
+            latin:keyStyle="numKeyStyle"
+            latin:keyWidth="8.047%p" />
+        <Key
             latin:keyStyle="num7KeyStyle"
             latin:keyXPos="43.125%p" />
         <Key
@@ -98,7 +108,7 @@
         <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
         <Spacer
             latin:keyWidth="0%p" />
-        </Row>
+    </Row>
     <Row>
         <switch>
             <case latin:hasSettingsKey="true">
@@ -114,8 +124,8 @@
         </switch>
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyXPos="20.400%p"
-            latin:keyWidth="16.084%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="24.140%p" />
         <Key
             latin:keyStyle="numStarKeyStyle"
             latin:keyXPos="43.125%p" />
diff --git a/java/res/xml-sw768dp/rows_phone_shift.xml b/java/res/xml-sw768dp/rows_phone_shift.xml
deleted file mode 100644
index 5861998..0000000
--- a/java/res/xml-sw768dp/rows_phone_shift.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
-    <include
-        latin:keyboardLayout="@xml/key_styles_common" />
-    <include
-        latin:keyboardLayout="@xml/key_styles_number" />
-    <Row>
-        <Key
-            latin:keyStyle="numTabKeyStyle"
-            latin:keyLabelFlags="alignLeft"
-            latin:keyWidth="11.172%p" />
-        <Key
-            latin:keyLabel="-"
-            latin:keyStyle="numKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="+"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="numPauseKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num1KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num2KeyStyle" />
-        <Key
-            latin:keyStyle="num3KeyStyle" />
-        <Key
-            latin:keyStyle="deleteKeyStyle"
-            latin:keyXPos="-11.172%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="backFromMoreSymbolKeyStyle"
-            latin:keyWidth="11.172%p" />
-        <Key
-            latin:keyLabel=","
-            latin:keyStyle="numKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="."
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="numWaitKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num4KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num5KeyStyle" />
-        <Key
-            latin:keyStyle="num6KeyStyle" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-11.172%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="13.829%p" />
-        <Key
-            latin:keyLabel="("
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel=")"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="N"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num7KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num8KeyStyle" />
-        <Key
-            latin:keyStyle="num9KeyStyle" />
-        <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-        <Spacer
-            latin:keyWidth="0%p" />
-    </Row>
-    <Row>
-        <switch>
-            <case latin:hasSettingsKey="true">
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-                <Spacer
-                    latin:keyWidth="8.047%p" />
-            </default>
-        </switch>
-        <Key
-            latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="24.140%p" />
-        <Key
-            latin:keyStyle="numStarKeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num0KeyStyle" />
-        <Key
-            latin:keyLabel="#"
-            latin:keyStyle="numKeyStyle" />
-        <switch>
-            <case
-                latin:shortcutKeyEnabled="true"
-            >
-                <Key
-                    latin:keyStyle="shortcutKeyStyle"
-                    latin:keyXPos="-8.047%p"
-                    latin:keyWidth="fillRight" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-                <Spacer
-                    latin:keyWidth="0%p" />
-            </default>
-        </switch>
-    </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/rows_symbols.xml b/java/res/xml-sw768dp/rows_symbols.xml
index 7458b36..2ba9357 100644
--- a/java/res/xml-sw768dp/rows_symbols.xml
+++ b/java/res/xml-sw768dp/rows_symbols.xml
@@ -102,12 +102,8 @@
         <Key
             latin:keyLabel="+"
             latin:moreKeys="@string/more_keys_for_plus" />
-        <Key
-            latin:keyLabel="("
-            latin:moreKeys="[,{,&lt;" />
-        <Key
-            latin:keyLabel=")"
-            latin:moreKeys="],},&gt;" />
+        <include
+            latin:keyboardLayout="@xml/keys_parentheses" />
         <Key
             latin:keyStyle="returnKeyStyle"
             latin:keyXPos="-15.704%p"
@@ -119,12 +115,8 @@
         <Key
             latin:keyStyle="toMoreSymbolKeyStyle"
             latin:keyWidth="13.829%p" />
-        <Key
-            latin:keyLabel="&lt;"
-            latin:moreKeys="≤,«,‹" />
-        <Key
-            latin:keyLabel="&gt;"
-            latin:moreKeys="≥,»,›" />
+        <include
+            latin:keyboardLayout="@xml/keys_less_greater" />
         <Key
             latin:keyLabel="="
             latin:moreKeys="≠,≈" />
@@ -133,8 +125,7 @@
                 latin:mode="url"
             >
                 <Key
-                    latin:keyLabel="\'"
-                    latin:moreKeys="‘,’,‚,‛" />
+                    latin:keyLabel="\'" />
             </case>
             <default>
                 <Key
@@ -181,11 +172,10 @@
             latin:keyStyle="spaceKeyStyle"
             latin:keyXPos="31.250%p"
             latin:keyWidth="37.500%p" />
-        <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
-        <!-- latin:moreKeys="“,”,„,‟,«,»,‘,’,‚,‛" -->
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="“,”,«,»,‘,’,‚,‛" />
+            latin:moreKeys="@string/more_keys_for_tablet_double_quote"
+            latin:maxMoreKeysColumn="4" />
         <Key
             latin:keyLabel="_" />
         <switch>
diff --git a/java/res/xml-sw768dp/rows_symbols_shift.xml b/java/res/xml-sw768dp/rows_symbols_shift.xml
index 80735b6..aba9c23 100644
--- a/java/res/xml-sw768dp/rows_symbols_shift.xml
+++ b/java/res/xml-sw768dp/rows_symbols_shift.xml
@@ -84,10 +84,8 @@
         <Key
             latin:keyLabel="±"
             latin:moreKeys="∞" />
-        <Key
-            latin:keyLabel="{" />
-        <Key
-            latin:keyLabel="}" />
+        <include
+            latin:keyboardLayout="@xml/keys_curly_brackets" />
         <Key
             latin:keyStyle="returnKeyStyle"
             latin:keyXPos="-15.704%p"
@@ -109,10 +107,8 @@
             latin:keyLabel="™" />
         <Key
             latin:keyLabel="℅" />
-        <Key
-            latin:keyLabel="[" />
-        <Key
-            latin:keyLabel="]" />
+        <include
+            latin:keyboardLayout="@xml/keys_square_brackets" />
         <Key
             latin:keyLabel="¡" />
         <Key
diff --git a/java/res/xml-tr/keyboard_set.xml b/java/res/xml-tr/keyboard_set.xml
index 3c42958..da79758 100644
--- a/java/res/xml-tr/keyboard_set.xml
+++ b/java/res/xml-tr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-uk/keyboard_set.xml b/java/res/xml-uk/keyboard_set.xml
index 300eea2..8eb9ecc 100644
--- a/java/res/xml-uk/keyboard_set.xml
+++ b/java/res/xml-uk/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-vi/keyboard_set.xml b/java/res/xml-vi/keyboard_set.xml
index 0b92c94..6d38eb1 100644
--- a/java/res/xml-vi/keyboard_set.xml
+++ b/java/res/xml-vi/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml/kbd_arabic.xml b/java/res/xml/kbd_arabic.xml
index d7f77cc..ce5f30b 100644
--- a/java/res/xml/kbd_arabic.xml
+++ b/java/res/xml/kbd_arabic.xml
@@ -20,7 +20,6 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
 >
     <include
         latin:keyboardLayout="@xml/rows_arabic" />
diff --git a/java/res/xml/kbd_hebrew.xml b/java/res/xml/kbd_hebrew.xml
index 3d574db..74836f3 100644
--- a/java/res/xml/kbd_hebrew.xml
+++ b/java/res/xml/kbd_hebrew.xml
@@ -20,7 +20,6 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
 >
     <include
         latin:keyboardLayout="@xml/rows_hebrew" />
diff --git a/java/res/xml/kbd_phone_shift.xml b/java/res/xml/kbd_phone_symbols.xml
similarity index 93%
rename from java/res/xml/kbd_phone_shift.xml
rename to java/res/xml/kbd_phone_symbols.xml
index 104f33f..7f59a85 100644
--- a/java/res/xml/kbd_phone_shift.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -23,5 +23,5 @@
     latin:keyWidth="26.67%p"
 >
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone_symbols" />
 </Keyboard>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 8d01e0f..14ee19e 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -180,7 +180,7 @@
     <key-style
         latin:styleName="spaceKeyStyle"
         latin:code="@integer/key_space"
-        latin:keyActionFlags="noKeyPreview"
+        latin:keyActionFlags="noKeyPreview|enableLongPress"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="shortcutKeyStyle"
diff --git a/java/res/xml/key_styles_number.xml b/java/res/xml/key_styles_number.xml
index 003165d..7307a1a 100644
--- a/java/res/xml/key_styles_number.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -45,6 +45,7 @@
         latin:styleName="num0KeyStyle"
         latin:code="48"
         latin:keyLabel="0 +"
+        latin:keyActionFlags="enableLongPress"
         latin:parentStyle="numberKeyStyle" />
     <key-style
         latin:styleName="num1KeyStyle"
@@ -95,14 +96,15 @@
         latin:code="42"
         latin:keyLabel="\uff0a"
         latin:parentStyle="numKeyStyle" />
+    <!-- Only for non-tablet device -->
     <key-style
-        latin:styleName="numSwitchToAltKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:styleName="numPhoneToSymbolKeyStyle"
+        latin:code="@integer/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_symbols_key"
         latin:parentStyle="numModeKeyStyle" />
     <key-style
-        latin:styleName="numSwitchToNumericKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:styleName="numPhoneToNumericKeyStyle"
+        latin:code="@integer/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_numeric_key"
         latin:parentStyle="numModeKeyStyle" />
     <key-style
@@ -125,5 +127,6 @@
         latin:styleName="numSpaceKeyStyle"
         latin:code="@integer/key_space"
         latin:keyIcon="iconSpaceKeyForNumberLayout"
+        latin:keyActionFlags="enableLongPress"
         latin:parentStyle="numKeyBaseStyle" />
 </merge>
diff --git a/java/res/xml/keyboard_set.xml b/java/res/xml/keyboard_set.xml
index ebdd990..1398b13 100644
--- a/java/res/xml/keyboard_set.xml
+++ b/java/res/xml/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml/keys_curly_brackets.xml
similarity index 70%
copy from java/res/xml-land/kbd_phone_shift.xml
copy to java/res/xml/keys_curly_brackets.xml
index f456a17..b43fbb1 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml/keys_curly_brackets.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -18,11 +18,13 @@
 */
 -->
 
-<Keyboard
+<merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
-    latin:keyWidth="26.67%p"
 >
-    <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
-</Keyboard>
+    <Key
+        latin:keyLabel="{"
+        latin:keyOutputText="@string/output_text_for_left_curly_bracket" />
+    <Key
+        latin:keyLabel="}"
+        latin:keyOutputText="@string/output_text_for_right_curly_bracket" />
+</merge>
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml/keys_less_greater.xml
similarity index 63%
copy from java/res/xml-land/kbd_phone_shift.xml
copy to java/res/xml/keys_less_greater.xml
index f456a17..8e90199 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml/keys_less_greater.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -18,11 +18,15 @@
 */
 -->
 
-<Keyboard
+<merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
-    latin:keyWidth="26.67%p"
 >
-    <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
-</Keyboard>
+    <Key
+        latin:keyLabel="&lt;"
+        latin:keyOutputText="@string/output_text_for_less_than"
+        latin:moreKeys="@string/more_keys_for_less_than" />
+    <Key
+        latin:keyLabel="&gt;"
+        latin:keyOutputText="@string/output_text_for_greater_than"
+        latin:moreKeys="@string/more_keys_for_greater_than" />
+</merge>
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml/keys_parentheses.xml
similarity index 62%
copy from java/res/xml-land/kbd_phone_shift.xml
copy to java/res/xml/keys_parentheses.xml
index f456a17..bacb26d 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml/keys_parentheses.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -18,11 +18,15 @@
 */
 -->
 
-<Keyboard
+<merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
-    latin:keyWidth="26.67%p"
 >
-    <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
-</Keyboard>
+    <Key
+        latin:keyLabel="("
+        latin:keyOutputText="@string/output_text_for_left_parenthesis"
+        latin:moreKeys="@string/more_keys_for_left_parenthesis" />
+    <Key
+        latin:keyLabel=")"
+        latin:keyOutputText="@string/output_text_for_right_parenthesis"
+        latin:moreKeys="@string/more_keys_for_right_parenthesis" />
+</merge>
diff --git a/java/res/xml-ar/kbd_symbols_shift.xml b/java/res/xml/keys_square_brackets.xml
similarity index 70%
rename from java/res/xml-ar/kbd_symbols_shift.xml
rename to java/res/xml/keys_square_brackets.xml
index 820b425..3525f4d 100644
--- a/java/res/xml-ar/kbd_symbols_shift.xml
+++ b/java/res/xml/keys_square_brackets.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -18,10 +18,13 @@
 */
 -->
 
-<Keyboard
+<merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:isRtlKeyboard="true"
 >
-    <include
-        latin:keyboardLayout="@xml/rows_symbols_shift" />
-</Keyboard>
+    <Key
+        latin:keyLabel="["
+        latin:keyOutputText="@string/output_text_for_left_square_bracket" />
+    <Key
+        latin:keyLabel="]"
+        latin:keyOutputText="@string/output_text_for_right_square_bracket" />
+</merge>
diff --git a/java/res/xml/rows_azerty.xml b/java/res/xml/rows_azerty.xml
index 142ebc0..533c683 100644
--- a/java/res/xml/rows_azerty.xml
+++ b/java/res/xml/rows_azerty.xml
@@ -130,9 +130,13 @@
         <Key
             latin:keyLabel="n"
             latin:moreKeys="@string/more_keys_for_n" />
+        <!-- TODO: Introduce a flag, such as strinctMoreKeysOrder, to control moreKeys display
+             order more precisely. -->
+        <!-- This key is close enough to right edge, so that the 4-more keys will be displayed in
+             order of "4,3,1,2". See @string/more_keys_for_single_quote -->
         <Key
             latin:keyLabel="\'"
-            latin:moreKeys="‘,’,‚,‛" />
+            latin:moreKeys="\u2018,\u2019,\u201b,\u201a" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight"
diff --git a/java/res/xml/rows_phone.xml b/java/res/xml/rows_phone.xml
index 94d0f72..18e4c9d 100644
--- a/java/res/xml/rows_phone.xml
+++ b/java/res/xml/rows_phone.xml
@@ -62,7 +62,7 @@
     </Row>
     <Row>
         <Key
-            latin:keyStyle="numSwitchToAltKeyStyle" />
+            latin:keyStyle="numPhoneToSymbolKeyStyle" />
         <Key
             latin:keyStyle="num0KeyStyle" />
         <Key
diff --git a/java/res/xml/rows_phone_shift.xml b/java/res/xml/rows_phone_symbols.xml
similarity index 97%
rename from java/res/xml/rows_phone_shift.xml
rename to java/res/xml/rows_phone_symbols.xml
index 1005206..dfa1349 100644
--- a/java/res/xml/rows_phone_shift.xml
+++ b/java/res/xml/rows_phone_symbols.xml
@@ -71,7 +71,7 @@
     </Row>
     <Row>
         <Key
-            latin:keyStyle="numSwitchToNumericKeyStyle" />
+            latin:keyStyle="numPhoneToNumericKeyStyle" />
         <Key
             latin:keyLabel="+"
             latin:keyStyle="numKeyStyle" />
diff --git a/java/res/xml/rows_symbols.xml b/java/res/xml/rows_symbols.xml
index d0d0edb..81a9a46 100644
--- a/java/res/xml/rows_symbols.xml
+++ b/java/res/xml/rows_symbols.xml
@@ -93,13 +93,8 @@
         <Key
             latin:keyLabel="+"
             latin:moreKeys="@string/more_keys_for_plus" />
-        <Key
-            latin:keyLabel="("
-            latin:moreKeys="@string/more_keys_for_left_parenthesis" />
-        <Key
-            latin:keyLabel=")"
-            latin:moreKeys="@string/more_keys_for_right_parenthesis"
-            latin:keyWidth="fillRight" />
+        <include
+            latin:keyboardLayout="@xml/keys_parentheses" />
     </Row>
     <Row
         latin:keyWidth="10%p"
@@ -111,15 +106,13 @@
         <Key
             latin:keyLabel="!"
             latin:moreKeys="¡" />
-        <!-- Note: Neither DroidSans nor Roboto have a glyph for ‟ Double high-reversed-9 quotation mark U+201F. -->
-            <!-- latin:moreKeys="“,”,„,‟,«,»" -->
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="“,”,«,»"
-            latin:maxMoreKeysColumn="6" />
+            latin:moreKeys="@string/more_keys_for_double_quote"
+            latin:maxMoreKeysColumn="4" />
         <Key
             latin:keyLabel="\'"
-            latin:moreKeys="‘,’,‚,‛" />
+            latin:moreKeys="@string/more_keys_for_single_quote" />
         <Key
             latin:keyLabel=":" />
         <Key
diff --git a/java/res/xml/rows_symbols_shift.xml b/java/res/xml/rows_symbols_shift.xml
index 6d1838c..828bd06 100644
--- a/java/res/xml/rows_symbols_shift.xml
+++ b/java/res/xml/rows_symbols_shift.xml
@@ -46,11 +46,8 @@
             latin:keyLabel="÷" />
         <Key
             latin:keyLabel="×" />
-        <Key
-            latin:keyLabel="{" />
-        <Key
-            latin:keyLabel="}"
-            latin:keyWidth="fillRight" />
+        <include
+            latin:keyboardLayout="@xml/keys_curly_brackets" />
     </Row>
     <Row
         latin:keyWidth="10%p"
@@ -74,11 +71,8 @@
         <Key
             latin:keyLabel="="
             latin:moreKeys="≠,≈,∞" />
-        <Key
-            latin:keyLabel="[" />
-        <Key
-            latin:keyLabel="]"
-            latin:keyWidth="fillRight" />
+        <include
+            latin:keyboardLayout="@xml/keys_square_brackets" />
     </Row>
     <Row
         latin:keyWidth="10%p"
@@ -98,12 +92,8 @@
             latin:moreKeys="§" />
         <Key
             latin:keyLabel="\\" />
-        <Key
-            latin:keyLabel="&lt;"
-            latin:moreKeys="≤,«,‹" />
-        <Key
-            latin:keyLabel="&gt;"
-            latin:moreKeys="≥,»,›" />
+        <include
+            latin:keyboardLayout="@xml/keys_less_greater" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight"
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index a715350..6ea926d 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -38,12 +38,6 @@
     // Map of key codes to spoken description resource IDs
     private final HashMap<Integer, Integer> mKeyCodeMap;
 
-    // Map of shifted key codes to spoken description resource IDs
-    private final HashMap<Integer, Integer> mShiftedKeyCodeMap;
-
-    // Map of shift-locked key codes to spoken description resource IDs
-    private final HashMap<Integer, Integer> mShiftLockedKeyCodeMap;
-
     public static void init() {
         sInstance.initInternal();
     }
@@ -55,8 +49,6 @@
     private KeyCodeDescriptionMapper() {
         mKeyLabelMap = new HashMap<CharSequence, Integer>();
         mKeyCodeMap = new HashMap<Integer, Integer>();
-        mShiftedKeyCodeMap = new HashMap<Integer, Integer>();
-        mShiftLockedKeyCodeMap = new HashMap<Integer, Integer>();
     }
 
     private void initInternal() {
@@ -71,15 +63,10 @@
         mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return);
         mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings);
         mKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift);
+        mKeyCodeMap.put(Keyboard.CODE_CAPSLOCK, R.string.spoken_description_caps_lock);
         mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic);
         mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
         mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab);
-
-        // Shifted versions of non-character codes defined in Keyboard
-        mShiftedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift_shifted);
-
-        // Shift-locked versions of non-character codes defined in Keyboard
-        mShiftLockedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_caps_lock);
     }
 
     /**
@@ -103,12 +90,18 @@
      */
     public CharSequence getDescriptionForKey(Context context, Keyboard keyboard, Key key,
             boolean shouldObscure) {
-        if (key.mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+        final int code = key.mCode;
+
+        if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
             final CharSequence description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
             if (description != null)
                 return description;
         }
 
+        if (code == Keyboard.CODE_SHIFT) {
+            return getDescriptionForShiftKey(context, keyboard);
+        }
+
         if (!TextUtils.isEmpty(key.mLabel)) {
             final String label = key.mLabel.toString().trim();
 
@@ -153,6 +146,27 @@
     }
 
     /**
+     * Returns a context-sensitive description of the "Shift" key.
+     *
+     * @param context The package's context.
+     * @param keyboard The keyboard on which the key resides.
+     * @return A context-sensitive description of the "Shift" key.
+     */
+    private CharSequence getDescriptionForShiftKey(Context context, Keyboard keyboard) {
+        final int resId;
+
+        if (keyboard.isShiftLocked()) {
+            resId = R.string.spoken_description_caps_lock;
+        } else if (keyboard.isShiftedOrShiftLocked()) {
+            resId = R.string.spoken_description_shift_shifted;
+        } else {
+            resId = R.string.spoken_description_shift;
+        }
+
+        return context.getString(resId);
+    }
+
+    /**
      * Returns a localized character sequence describing what will happen when
      * the specified key is pressed based on its key code.
      * <p>
@@ -177,12 +191,6 @@
             boolean shouldObscure) {
         final int code = key.mCode;
 
-        if (keyboard.isShiftLocked() && mShiftLockedKeyCodeMap.containsKey(code)) {
-            return context.getString(mShiftLockedKeyCodeMap.get(code));
-        } else if (keyboard.isShiftedOrShiftLocked() && mShiftedKeyCodeMap.containsKey(code)) {
-            return context.getString(mShiftedKeyCodeMap.get(code));
-        }
-
         // If the key description should be obscured, now is the time to do it.
         final boolean isDefinedNonCtrl = Character.isDefined(code) && !Character.isISOControl(code);
         if (shouldObscure && isDefinedNonCtrl) {
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index d4419ae..5e58821 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -36,8 +36,6 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * Class for describing the position and characteristics of a single key in the keyboard.
@@ -120,6 +118,7 @@
     private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
     private static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02;
     private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
+    private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
 
     private final int mHashCode;
 
@@ -128,45 +127,6 @@
     /** Key is enabled and responds on press */
     private boolean mEnabled = true;
 
-    // RTL parenthesis character swapping map.
-    private static final Map<Integer, Integer> sRtlParenthesisMap = new HashMap<Integer, Integer>();
-
-    static {
-        // The all letters need to be mirrored are found at
-        // http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt
-        addRtlParenthesisPair('(', ')');
-        addRtlParenthesisPair('[', ']');
-        addRtlParenthesisPair('{', '}');
-        addRtlParenthesisPair('<', '>');
-        // \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-        // \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-        addRtlParenthesisPair('\u00ab', '\u00bb');
-        // \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-        // \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-        addRtlParenthesisPair('\u2039', '\u203a');
-        // \u2264: LESS-THAN OR EQUAL TO
-        // \u2265: GREATER-THAN OR EQUAL TO
-        addRtlParenthesisPair('\u2264', '\u2265');
-    }
-
-    private static void addRtlParenthesisPair(int left, int right) {
-        sRtlParenthesisMap.put(left, right);
-        sRtlParenthesisMap.put(right, left);
-    }
-
-    public static int getRtlParenthesisCode(int code, boolean isRtl) {
-        if (isRtl && sRtlParenthesisMap.containsKey(code)) {
-            return sRtlParenthesisMap.get(code);
-        } else {
-            return code;
-        }
-    }
-
-    private static int getCode(Resources res, Keyboard.Params params, String moreKeySpec) {
-        return getRtlParenthesisCode(
-                MoreKeySpecParser.getCode(res, moreKeySpec), params.mIsRtlKeyboard);
-    }
-
     private static Drawable getIcon(Keyboard.Params params, String moreKeySpec) {
         final int iconAttrId = MoreKeySpecParser.getIconAttrId(moreKeySpec);
         if (iconAttrId == KeyboardIconsSet.ICON_UNDEFINED) {
@@ -182,7 +142,8 @@
     public Key(Resources res, Keyboard.Params params, String moreKeySpec,
             int x, int y, int width, int height) {
         this(params, MoreKeySpecParser.getLabel(moreKeySpec), null, getIcon(params, moreKeySpec),
-                getCode(res, params, moreKeySpec), MoreKeySpecParser.getOutputText(moreKeySpec),
+                MoreKeySpecParser.getCode(res, moreKeySpec),
+                MoreKeySpecParser.getOutputText(moreKeySpec),
                 x, y, width, height);
     }
 
@@ -265,7 +226,6 @@
 
         mBackgroundType = style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_backgroundType, BACKGROUND_TYPE_NORMAL);
-        mActionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0);
 
         final KeyboardIconsSet iconsSet = params.mIconsSet;
         mVisualInsetsLeft = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
@@ -282,17 +242,19 @@
 
         mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags, 0);
         final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
-
+        int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0);
         final String[] additionalMoreKeys = style.getStringArray(
                 keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
         final String[] moreKeys = MoreKeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
                 keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
         if (moreKeys != null) {
+            actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
             for (int i = 0; i < moreKeys.length; i++) {
                 moreKeys[i] = adjustCaseOfStringForKeyboardId(
                         moreKeys[i], preserveCase, params.mId);
             }
         }
+        mActionFlags = actionFlags;
         mMoreKeys = moreKeys;
         mMaxMoreKeysColumn = style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn);
@@ -309,16 +271,14 @@
         if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
                 && !TextUtils.isEmpty(mLabel)) {
             if (mLabel.codePointCount(0, mLabel.length()) == 1) {
-                final int activatedCode;
                 // Use the first letter of the hint label if shiftedLetterActivated flag is
                 // specified.
                 if (hasShiftedLetterHint() && isShiftedLetterActivated()
                         && !TextUtils.isEmpty(mHintLabel)) {
-                    activatedCode = mHintLabel.codePointAt(0);
+                    mCode = mHintLabel.codePointAt(0);
                 } else {
-                    activatedCode = mLabel.codePointAt(0);
+                    mCode = mLabel.codePointAt(0);
                 }
-                mCode = getRtlParenthesisCode(activatedCode, params.mIsRtlKeyboard);
             } else {
                 // In some locale and case, the character might be represented by multiple code
                 // points, such as upper case Eszett of German alphabet.
@@ -420,7 +380,7 @@
     @Override
     public String toString() {
         String top = Keyboard.printableCode(mCode);
-        if (mLabel != null && mLabel.length() != 1) {
+        if (mLabel != null && mLabel.codePointCount(0, mLabel.length()) != 1) {
             top += "/\"" + mLabel + '"';
         }
         return String.format("%s %d,%d", top, mX, mY);
@@ -466,6 +426,12 @@
         return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0;
     }
 
+    public boolean isLongPressEnabled() {
+        // We need not start long press timer on the key which has activated shifted letter.
+        return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0
+                && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
+    }
+
     public Typeface selectTypeface(Typeface defaultTypeface) {
         // TODO: Handle "bold" here too?
         if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 8832d8f..6653dec 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -92,7 +92,6 @@
      */
     public static final int CODE_SHIFT = -1;
     public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
-    public static final int CODE_CAPSLOCK = -3;
     public static final int CODE_OUTPUT_TEXT = -4;
     public static final int CODE_DELETE = -5;
     public static final int CODE_SETTINGS = -6;
@@ -122,9 +121,6 @@
     /** Maximum column for mini keyboard */
     public final int mMaxMiniKeyboardColumn;
 
-    /** True if Right-To-Left keyboard */
-    public final boolean mIsRtlKeyboard;
-
     /** List of keys and icons in this keyboard */
     public final Set<Key> mKeys;
     public final Set<Key> mShiftKeys;
@@ -141,7 +137,6 @@
         mOccupiedWidth = params.mOccupiedWidth;
         mMostCommonKeyHeight = params.mMostCommonKeyHeight;
         mMostCommonKeyWidth = params.mMostCommonKeyWidth;
-        mIsRtlKeyboard = params.mIsRtlKeyboard;
         mMoreKeysTemplate = params.mMoreKeysTemplate;
         mMaxMiniKeyboardColumn = params.mMaxMiniKeyboardColumn;
 
@@ -223,7 +218,6 @@
         public int mHorizontalGap;
         public int mVerticalGap;
 
-        public boolean mIsRtlKeyboard;
         public int mMoreKeysTemplate;
         public int mMaxMiniKeyboardColumn;
 
@@ -368,9 +362,9 @@
         switch (code) {
         case CODE_SHIFT: return "shift";
         case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
-        case CODE_CAPSLOCK: return "capslock";
         case CODE_OUTPUT_TEXT: return "text";
         case CODE_DELETE: return "delete";
+        case CODE_SETTINGS: return "settings";
         case CODE_SHORTCUT: return "shortcut";
         case CODE_UNSPECIFIED: return "unspec";
         case CODE_TAB: return "tab";
@@ -740,8 +734,6 @@
                         R.styleable.Keyboard_rowHeight, params.mBaseHeight,
                         params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
 
-                params.mIsRtlKeyboard = keyboardAttr.getBoolean(
-                        R.styleable.Keyboard_isRtlKeyboard, false);
                 params.mMoreKeysTemplate = keyboardAttr.getResourceId(
                         R.styleable.Keyboard_moreKeysTemplate, 0);
                 params.mMaxMiniKeyboardColumn = keyAttr.getInt(
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 997b952..0837e17 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -46,7 +46,7 @@
     public static final int ELEMENT_SYMBOLS = 5;
     public static final int ELEMENT_SYMBOLS_SHIFTED = 6;
     public static final int ELEMENT_PHONE = 7;
-    public static final int ELEMENT_PHONE_SHIFTED = 8;
+    public static final int ELEMENT_PHONE_SYMBOLS = 8;
     public static final int ELEMENT_NUMBER = 9;
 
     private static final int F2KEY_MODE_NONE = 0;
@@ -145,11 +145,11 @@
     }
 
     public boolean isPhoneKeyboard() {
-        return mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SHIFTED;
+        return mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS;
     }
 
     public boolean isPhoneShiftKeyboard() {
-        return mElementId == ELEMENT_PHONE_SHIFTED;
+        return mElementId == ELEMENT_PHONE_SYMBOLS;
     }
 
     public boolean navigateAction() {
@@ -237,7 +237,7 @@
         case ELEMENT_SYMBOLS: return "symbols";
         case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted";
         case ELEMENT_PHONE: return "phone";
-        case ELEMENT_PHONE_SHIFTED: return "phoneShifted";
+        case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols";
         case ELEMENT_NUMBER: return "number";
         default: return null;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index d35948b..664e765 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -119,9 +119,11 @@
         final int keyboardSetElementId;
         switch (mParams.mMode) {
         case KeyboardId.MODE_PHONE:
-            keyboardSetElementId =
-                    (baseKeyboardSetElementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED)
-                    ? KeyboardId.ELEMENT_PHONE_SHIFTED : KeyboardId.ELEMENT_PHONE;
+            if (baseKeyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
+                keyboardSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
+            } else {
+                keyboardSetElementId = KeyboardId.ELEMENT_PHONE;
+            }
             break;
         case KeyboardId.MODE_NUMBER:
             keyboardSetElementId = KeyboardId.ELEMENT_NUMBER;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 951bcdb..5ba560d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -194,6 +194,9 @@
     }
 
     public void onPressKey(int code) {
+        if (isVibrateAndSoundFeedbackRequired()) {
+            mInputMethodService.hapticAndAudioFeedback(code);
+        }
         mState.onPressKey(code);
     }
 
@@ -271,11 +274,31 @@
                 ? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false;
     }
 
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
+    public void startLongPressTimer(int code) {
+        final LatinKeyboardView keyboardView = getKeyboardView();
+        if (keyboardView != null) {
+            final TimerProxy timer = keyboardView.getTimerProxy();
+            timer.startLongPressTimer(code);
+        }
+    }
+
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
+    public void hapticAndAudioFeedback(int code) {
+        mInputMethodService.hapticAndAudioFeedback(code);
+    }
+
+    public void onLongPressTimeout(int code) {
+        mState.onLongPressTimeout(code);
+    }
+
     public boolean isInMomentarySwitchState() {
         return mState.isInMomentarySwitchState();
     }
 
-    public boolean isVibrateAndSoundFeedbackRequired() {
+    private boolean isVibrateAndSoundFeedbackRequired() {
         return mKeyboardView != null && !mKeyboardView.isInSlidingKeyInput();
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 5aad67d..f3583fe 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -117,12 +117,12 @@
         private static final int MSG_DOUBLE_TAP = 3;
         private static final int MSG_KEY_TYPED = 4;
 
-        private final int mKeyRepeatInterval;
+        private final KeyTimerParams mParams;
         private boolean mInKeyRepeat;
 
-        public KeyTimerHandler(LatinKeyboardView outerInstance, int keyRepeatInterval) {
+        public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) {
             super(outerInstance);
-            mKeyRepeatInterval = keyRepeatInterval;
+            mParams = params;
         }
 
         @Override
@@ -132,18 +132,23 @@
             switch (msg.what) {
             case MSG_REPEAT_KEY:
                 tracker.onRepeatKey(tracker.getKey());
-                startKeyRepeatTimer(mKeyRepeatInterval, tracker);
+                startKeyRepeatTimer(tracker);
                 break;
             case MSG_LONGPRESS_KEY:
-                keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker);
+                if (tracker != null) {
+                    keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker);
+                } else {
+                    KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1);
+                }
                 break;
             }
         }
 
         @Override
-        public void startKeyRepeatTimer(long delay, PointerTracker tracker) {
+        public void startKeyRepeatTimer(PointerTracker tracker) {
             mInKeyRepeat = true;
-            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay);
+            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker),
+                    mParams.mKeyRepeatStartTimeout);
         }
 
         public void cancelKeyRepeatTimer() {
@@ -156,9 +161,49 @@
         }
 
         @Override
-        public void startLongPressTimer(long delay, PointerTracker tracker) {
+        public void startLongPressTimer(int code) {
             cancelLongPressTimer();
-            sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+            final int delay;
+            switch (code) {
+            case Keyboard.CODE_SHIFT:
+                delay = mParams.mLongPressShiftKeyTimeout;
+                break;
+            default:
+                delay = 0;
+                break;
+            }
+            if (delay > 0) {
+                sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, code, 0), delay);
+            }
+        }
+
+        @Override
+        public void startLongPressTimer(PointerTracker tracker) {
+            cancelLongPressTimer();
+            if (tracker != null) {
+                final Key key = tracker.getKey();
+                final int delay;
+                switch (key.mCode) {
+                case Keyboard.CODE_SHIFT:
+                    delay = mParams.mLongPressShiftKeyTimeout;
+                    break;
+                case Keyboard.CODE_SPACE:
+                    delay = mParams.mLongPressSpaceKeyTimeout;
+                    break;
+                default:
+                    if (KeyboardSwitcher.getInstance().isInMomentarySwitchState()) {
+                        // We use longer timeout for sliding finger input started from the symbols
+                        // mode key.
+                        delay = mParams.mLongPressKeyTimeout * 3;
+                    } else {
+                        delay = mParams.mLongPressKeyTimeout;
+                    }
+                    break;
+                }
+                if (delay > 0) {
+                    sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+                }
+            }
         }
 
         @Override
@@ -167,9 +212,9 @@
         }
 
         @Override
-        public void startKeyTypedTimer(long delay) {
+        public void startKeyTypedTimer() {
             removeMessages(MSG_KEY_TYPED);
-            sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), delay);
+            sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), mParams.mIgnoreSpecialKeyTimeout);
         }
 
         @Override
@@ -201,11 +246,6 @@
 
     public static class PointerTrackerParams {
         public final boolean mSlidingKeyInputEnabled;
-        public final int mKeyRepeatStartTimeout;
-        public final int mLongPressKeyTimeout;
-        public final int mLongPressShiftKeyTimeout;
-        public final int mLongPressSpaceKeyTimeout;
-        public final int mIgnoreSpecialKeyTimeout;
         public final int mTouchNoiseThresholdTime;
         public final float mTouchNoiseThresholdDistance;
 
@@ -213,11 +253,6 @@
 
         private PointerTrackerParams() {
             mSlidingKeyInputEnabled = false;
-            mKeyRepeatStartTimeout = 0;
-            mLongPressKeyTimeout = 0;
-            mLongPressShiftKeyTimeout = 0;
-            mLongPressSpaceKeyTimeout = 0;
-            mIgnoreSpecialKeyTimeout = 0;
             mTouchNoiseThresholdTime =0;
             mTouchNoiseThresholdDistance = 0;
         }
@@ -225,8 +260,35 @@
         public PointerTrackerParams(TypedArray latinKeyboardViewAttr) {
             mSlidingKeyInputEnabled = latinKeyboardViewAttr.getBoolean(
                     R.styleable.LatinKeyboardView_slidingKeyInputEnable, false);
+            mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
+                    R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
+            mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
+                    R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
+        }
+    }
+
+    static class KeyTimerParams {
+        public final int mKeyRepeatStartTimeout;
+        public final int mKeyRepeatInterval;
+        public final int mLongPressKeyTimeout;
+        public final int mLongPressShiftKeyTimeout;
+        public final int mLongPressSpaceKeyTimeout;
+        public final int mIgnoreSpecialKeyTimeout;
+
+        KeyTimerParams() {
+            mKeyRepeatStartTimeout = 0;
+            mKeyRepeatInterval = 0;
+            mLongPressKeyTimeout = 0;
+            mLongPressShiftKeyTimeout = 0;
+            mLongPressSpaceKeyTimeout = 0;
+            mIgnoreSpecialKeyTimeout = 0;
+        }
+
+        public KeyTimerParams(TypedArray latinKeyboardViewAttr) {
             mKeyRepeatStartTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_keyRepeatStartTimeout, 0);
+            mKeyRepeatInterval = latinKeyboardViewAttr.getInt(
+                    R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
             mLongPressKeyTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_longPressKeyTimeout, 0);
             mLongPressShiftKeyTimeout = latinKeyboardViewAttr.getInt(
@@ -235,10 +297,6 @@
                     R.styleable.LatinKeyboardView_longPressSpaceKeyTimeout, 0);
             mIgnoreSpecialKeyTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_ignoreSpecialKeyTimeout, 0);
-            mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
-                    R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
-            mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
-                    R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
         }
     }
 
@@ -254,7 +312,7 @@
         mHasDistinctMultitouch = context.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
 
-        PointerTracker.init(mHasDistinctMultitouch, getContext());
+        PointerTracker.init(mHasDistinctMultitouch);
 
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView);
@@ -268,16 +326,14 @@
         mSpacebarTextShadowColor = a.getColor(
                 R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
 
+        final KeyTimerParams keyTimerParams = new KeyTimerParams(a);
         mPointerTrackerParams = new PointerTrackerParams(a);
-        mIsSpacebarTriggeringPopupByLongPress = (
-                mPointerTrackerParams.mLongPressSpaceKeyTimeout > 0);
+        mIsSpacebarTriggeringPopupByLongPress = (keyTimerParams.mLongPressSpaceKeyTimeout > 0);
 
         final float keyHysteresisDistance = a.getDimension(
                 R.styleable.LatinKeyboardView_keyHysteresisDistance, 0);
         mKeyDetector = new KeyDetector(keyHysteresisDistance);
-        final int keyRepeatInterval = a.getInt(
-                R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
-        mKeyTimerHandler = new KeyTimerHandler(this, keyRepeatInterval);
+        mKeyTimerHandler = new KeyTimerHandler(this, keyTimerParams);
         mConfigShowMiniKeyboardAtTouchedPoint = a.getBoolean(
                 R.styleable.LatinKeyboardView_showMiniKeyboardAtTouchedPoint, false);
         a.recycle();
@@ -425,12 +481,7 @@
             // Long pressing on 0 in phone number keypad gives you a '+'.
             invokeCodeInput(Keyboard.CODE_PLUS);
             invokeReleaseKey(primaryCode);
-            return true;
-        }
-        if (primaryCode == Keyboard.CODE_SHIFT && keyboard.mId.isAlphabetKeyboard()) {
-            tracker.onLongPressed();
-            invokeCodeInput(Keyboard.CODE_CAPSLOCK);
-            invokeReleaseKey(primaryCode);
+            KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
             return true;
         }
         if (primaryCode == Keyboard.CODE_SPACE) {
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 9742913..433bd0d 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -210,7 +210,6 @@
             // TODO: Mini keyboard's vertical gap is currently calculated heuristically.
             // Should revise the algorithm.
             mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
-            mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
             mMoreKeys = parentKey.mMoreKeys;
 
             final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index fc92a24..110f7f6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.keyboard;
 
-import android.content.Context;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -71,10 +70,11 @@
     }
 
     public interface TimerProxy {
-        public void startKeyTypedTimer(long delay);
+        public void startKeyTypedTimer();
         public boolean isTyping();
-        public void startKeyRepeatTimer(long delay, PointerTracker tracker);
-        public void startLongPressTimer(long delay, PointerTracker tracker);
+        public void startKeyRepeatTimer(PointerTracker tracker);
+        public void startLongPressTimer(PointerTracker tracker);
+        public void startLongPressTimer(int code);
         public void cancelLongPressTimer();
         public void startDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
@@ -82,13 +82,15 @@
 
         public static class Adapter implements TimerProxy {
             @Override
-            public void startKeyTypedTimer(long delay) {}
+            public void startKeyTypedTimer() {}
             @Override
             public boolean isTyping() { return false; }
             @Override
-            public void startKeyRepeatTimer(long delay, PointerTracker tracker) {}
+            public void startKeyRepeatTimer(PointerTracker tracker) {}
             @Override
-            public void startLongPressTimer(long delay, PointerTracker tracker) {}
+            public void startLongPressTimer(PointerTracker tracker) {}
+            @Override
+            public void startLongPressTimer(int code) {}
             @Override
             public void cancelLongPressTimer() {}
             @Override
@@ -159,7 +161,7 @@
     private static final KeyboardActionListener EMPTY_LISTENER =
             new KeyboardActionListener.Adapter();
 
-    public static void init(boolean hasDistinctMultitouch, Context context) {
+    public static void init(boolean hasDistinctMultitouch) {
         if (hasDistinctMultitouch) {
             sPointerTrackerQueue = new PointerTrackerQueue();
         } else {
@@ -269,7 +271,7 @@
                 mListener.onCodeInput(code, keyCodes, x, y);
             }
             if (!key.altCodeWhileTyping() && !key.isModifier()) {
-                mTimerProxy.startKeyTypedTimer(sParams.mIgnoreSpecialKeyTimeout);
+                mTimerProxy.startKeyTypedTimer();
             }
         }
     }
@@ -674,7 +676,7 @@
     private void startRepeatKey(Key key) {
         if (key != null && key.isRepeatable()) {
             onRepeatKey(key);
-            mTimerProxy.startKeyRepeatTimer(sParams.mKeyRepeatStartTimeout, this);
+            mTimerProxy.startKeyRepeatTimer(this);
             mIsRepeatableKey = true;
         } else {
             mIsRepeatableKey = false;
@@ -702,24 +704,8 @@
     }
 
     private void startLongPressTimer(Key key) {
-        if (key == null) return;
-        if (key.mCode == Keyboard.CODE_SHIFT) {
-            if (sParams.mLongPressShiftKeyTimeout > 0) {
-                mTimerProxy.startLongPressTimer(sParams.mLongPressShiftKeyTimeout, this);
-            }
-        } else if (key.mCode == Keyboard.CODE_SPACE) {
-            if (sParams.mLongPressSpaceKeyTimeout > 0) {
-                mTimerProxy.startLongPressTimer(sParams.mLongPressSpaceKeyTimeout, this);
-            }
-        } else if (key.hasShiftedLetterHint() && mKeyboard.isManualShifted()) {
-            // We need not start long press timer on the key which has manual temporary upper case
-            // code defined and the keyboard is in manual temporary upper case mode.
-            return;
-        } else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
-            // We use longer timeout for sliding finger input started from the symbols mode key.
-            mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout * 3, this);
-        } else {
-            mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout, this);
+        if (key != null && key.isLongPressEnabled()) {
+            mTimerProxy.startLongPressTimer(this);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 1450192..25a2c23 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.keyboard.internal;
 
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.util.Log;
 
@@ -28,7 +27,6 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 
 public class KeyStyles {
@@ -74,63 +72,8 @@
         protected static String[] parseStringArray(TypedArray a, int index) {
             if (!a.hasValue(index))
                 return null;
-            return parseCsvString(a.getString(index), a.getResources(), R.string.english_ime_name);
-        }
-    }
-
-    /* package for test */
-    static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
-        final String text = Utils.resolveStringResource(rawText, res, packageNameResId);
-        final int size = text.length();
-        if (size == 0) {
-            return null;
-        }
-        if (size == 1) {
-            return new String[] { text };
-        }
-
-        final StringBuilder sb = new StringBuilder();
-        ArrayList<String> list = null;
-        int start = 0;
-        for (int pos = 0; pos < size; pos++) {
-            final char c = text.charAt(pos);
-            if (c == ',') {
-                if (list == null) {
-                    list = new ArrayList<String>();
-                }
-                if (sb.length() == 0) {
-                    list.add(text.substring(start, pos));
-                } else {
-                    list.add(sb.toString());
-                    sb.setLength(0);
-                }
-                start = pos + 1;
-                continue;
-            } else if (c == Utils.ESCAPE_CHAR) {
-                if (start == pos) {
-                    // Skip escape character at the beginning of the value.
-                    start++;
-                    pos++;
-                } else {
-                    if (start < pos && sb.length() == 0) {
-                        sb.append(text.subSequence(start, pos));
-                    }
-                    pos++;
-                    if (pos < size) {
-                        sb.append(text.charAt(pos));
-                    }
-                }
-            } else if (sb.length() > 0) {
-                sb.append(c);
-            }
-        }
-        if (list == null) {
-            return new String[] {
-                    sb.length() > 0 ? sb.toString() : text.substring(start)
-            };
-        } else {
-            list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
-            return list.toArray(new String[list.size()]);
+            return Utils.parseCsvString(
+                    a.getString(index), a.getResources(), R.string.english_ime_name);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 1de8386..cb8b4f0 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -29,7 +29,7 @@
  * The input events are {@link #onLoadKeyboard(String)}, {@link #onSaveKeyboardState()},
  * {@link #onPressKey(int)}, {@link #onReleaseKey(int, boolean)},
  * {@link #onCodeInput(int, boolean, boolean)}, {@link #onCancelInput(boolean)},
- * {@link #onUpdateShiftState(boolean)}.
+ * {@link #onUpdateShiftState(boolean)}, {@link #onLongPressTimeout(int)}.
  *
  * The actions are {@link SwitchActions}'s methods.
  */
@@ -54,6 +54,8 @@
 
         public void startDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
+        public void startLongPressTimer(int code);
+        public void hapticAndAudioFeedback(int code);
     }
 
     private final SwitchActions mSwitchActions;
@@ -335,6 +337,24 @@
         mSymbolKeyState.onRelease();
     }
 
+    public void onLongPressTimeout(int code) {
+        if (DEBUG_EVENT) {
+            Log.d(TAG, "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " " + this);
+        }
+        if (mIsAlphabetMode && code == Keyboard.CODE_SHIFT) {
+            if (mAlphabetShiftState.isShiftLocked()) {
+                setShiftLocked(false);
+                // Shift key is long pressed while shift locked state, we will toggle back to normal
+                // state. And mark as if shift key is released.
+                mShiftKeyState.onRelease();
+            } else {
+                // Shift key is long pressed while shift unloked state.
+                setShiftLocked(true);
+            }
+            mSwitchActions.hapticAndAudioFeedback(code);
+        }
+    }
+
     public void onUpdateShiftState(boolean autoCaps) {
         if (DEBUG_EVENT) {
             Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + " " + this);
@@ -370,23 +390,27 @@
                     // Shift key has been double tapped while in normal state. This is the second
                     // tap to disable shift locked state, so just ignore this.
                 }
-            } else if (mAlphabetShiftState.isShiftLocked()) {
-                // Shift key is pressed while shift locked state, we will treat this state as
-                // shift lock shifted state and mark as if shift key pressed while normal state.
-                setShifted(SHIFT_LOCK_SHIFTED);
-                mShiftKeyState.onPress();
-            } else if (mAlphabetShiftState.isAutomaticShifted()) {
-                // Shift key is pressed while automatic shifted, we have to move to manual shifted.
-                setShifted(MANUAL_SHIFT);
-                mShiftKeyState.onPress();
-            } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
-                // In manual shifted state, we just record shift key has been pressing while
-                // shifted state.
-                mShiftKeyState.onPressOnShifted();
             } else {
-                // In base layout, chording or manual shifted mode is started.
-                setShifted(MANUAL_SHIFT);
-                mShiftKeyState.onPress();
+                if (mAlphabetShiftState.isShiftLocked()) {
+                    // Shift key is pressed while shift locked state, we will treat this state as
+                    // shift lock shifted state and mark as if shift key pressed while normal state.
+                    setShifted(SHIFT_LOCK_SHIFTED);
+                    mShiftKeyState.onPress();
+                } else if (mAlphabetShiftState.isAutomaticShifted()) {
+                    // Shift key is pressed while automatic shifted, we have to move to manual
+                    // shifted.
+                    setShifted(MANUAL_SHIFT);
+                    mShiftKeyState.onPress();
+                } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
+                    // In manual shifted state, we just record shift key has been pressing while
+                    // shifted state.
+                    mShiftKeyState.onPressOnShifted();
+                } else {
+                    // In base layout, chording or manual shifted mode is started.
+                    setShifted(MANUAL_SHIFT);
+                    mShiftKeyState.onPress();
+                }
+                mSwitchActions.startLongPressTimer(Keyboard.CODE_SHIFT);
             }
         } else {
             // In symbol mode, just toggle symbol and symbol more keyboard.
@@ -480,18 +504,6 @@
                     + " autoCaps=" + autoCaps + " " + this);
         }
 
-        if (mIsAlphabetMode && code == Keyboard.CODE_CAPSLOCK) {
-            if (mAlphabetShiftState.isShiftLocked()) {
-                setShiftLocked(false);
-                // Shift key is long pressed while shift locked state, we will toggle back to normal
-                // state. And mark as if shift key is released.
-                mShiftKeyState.onRelease();
-            } else {
-                // Shift key is long pressed while shift unloked state.
-                setShiftLocked(true);
-            }
-        }
-
         switch (mSwitchState) {
         case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
             if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1e71714..19cd16a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -59,7 +59,6 @@
 import com.android.inputmethod.compat.VibratorCompatWrapper;
 import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
 import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardActionListener;
 import com.android.inputmethod.keyboard.KeyboardId;
@@ -1296,10 +1295,6 @@
         case Keyboard.CODE_SETTINGS:
             onSettingsKeyPressed();
             break;
-        case Keyboard.CODE_CAPSLOCK:
-            // Caps lock code is handled in KeyboardSwitcher.onCodeInput() below.
-            hapticAndAudioFeedback(primaryCode);
-            break;
         case Keyboard.CODE_SHORTCUT:
             mSubtypeSwitcher.switchToShortcutIME();
             break;
@@ -1901,16 +1896,13 @@
             // So, LatinImeLogger logs "" as a user's input.
             LatinImeLogger.logOnManualSuggestion(
                     "", suggestion.toString(), index, suggestions.mWords);
+            final CharSequence outputText = mSettingsValues.mSuggestPuncOutputTextList
+                    .getWord(index);
+            final int primaryCode = outputText.charAt(0);
             // Find out whether the previous character is a space. If it is, as a special case
             // for punctuation entered through the suggestion strip, it should be swapped
             // if it was a magic or a weak space. This is meant to help in case the user
             // pressed space on purpose of displaying the suggestion strip punctuation.
-            final int rawPrimaryCode = suggestion.charAt(0);
-            // Maybe apply the "bidi mirrored" conversions for parentheses
-            final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
-            final boolean isRtl = keyboard != null && keyboard.mIsRtlKeyboard;
-            final int primaryCode = Key.getRtlParenthesisCode(rawPrimaryCode, isRtl);
-
             insertPunctuationFromSuggestionStrip(ic, primaryCode);
             // TODO: the following endBatchEdit seems useless, check
             if (ic != null) {
@@ -2294,18 +2286,14 @@
         loadSettings();
     }
 
-    private void hapticAndAudioFeedback(int primaryCode) {
+    public void hapticAndAudioFeedback(int primaryCode) {
         vibrate();
         playKeyClick(primaryCode);
     }
 
     @Override
     public void onPressKey(int primaryCode) {
-        final KeyboardSwitcher switcher = mKeyboardSwitcher;
-        if (switcher.isVibrateAndSoundFeedbackRequired()) {
-            hapticAndAudioFeedback(primaryCode);
-        }
-        switcher.onPressKey(primaryCode);
+        mKeyboardSwitcher.onPressKey(primaryCode);
     }
 
     @Override
@@ -2313,7 +2301,6 @@
         mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding);
     }
 
-
     // receive ringer mode change and network state change.
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index e6ef396..5f9cb8d 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -25,6 +25,7 @@
 
 import com.android.inputmethod.compat.InputTypeCompatUtils;
 import com.android.inputmethod.compat.VibratorCompatWrapper;
+import com.android.inputmethod.keyboard.internal.MoreKeySpecParser;
 
 import java.util.Arrays;
 import java.util.Locale;
@@ -36,8 +37,9 @@
     public final int mDelayUpdateOldSuggestions;
     public final String mMagicSpaceStrippers;
     public final String mMagicSpaceSwappers;
-    public final String mSuggestPuncs;
+    private final String mSuggestPuncs;
     public final SuggestedWords mSuggestPuncList;
+    public final SuggestedWords mSuggestPuncOutputTextList;
     private final String mSymbolsExcludedFromWordSeparators;
     public final String mWordSeparators;
     public final CharSequence mHintToSaveText;
@@ -98,9 +100,11 @@
                 }
             }
         }
-        mSuggestPuncs = res.getString(R.string.suggested_punctuations);
-        // TODO: it would be nice not to recreate this each time we change the configuration
-        mSuggestPuncList = createSuggestPuncList(mSuggestPuncs);
+        final String[] suggestPuncsSpec = Utils.parseCsvString(
+                res.getString(R.string.suggested_punctuations), res, R.string.english_ime_name);
+        mSuggestPuncs = createSuggestPuncs(suggestPuncsSpec);
+        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+        mSuggestPuncOutputTextList = createSuggestPuncOutputTextList(suggestPuncsSpec);
         mSymbolsExcludedFromWordSeparators =
                 res.getString(R.string.symbols_excluded_from_word_separators);
         mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers,
@@ -150,11 +154,36 @@
     }
 
     // Helper functions to create member values.
-    private static SuggestedWords createSuggestPuncList(final String puncs) {
-        SuggestedWords.Builder builder = new SuggestedWords.Builder();
+    private static String createSuggestPuncs(final String[] puncs) {
+        final StringBuilder sb = new StringBuilder();
         if (puncs != null) {
-            for (int i = 0; i < puncs.length(); i++) {
-                builder.addWord(puncs.subSequence(i, i + 1));
+            for (final String puncSpec : puncs) {
+                sb.append(MoreKeySpecParser.getLabel(puncSpec));
+            }
+        }
+        return sb.toString();
+    }
+
+    private static SuggestedWords createSuggestPuncList(final String[] puncs) {
+        final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+        if (puncs != null) {
+            for (final String puncSpec : puncs) {
+                builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
+            }
+        }
+        return builder.setIsPunctuationSuggestions().build();
+    }
+
+    private static SuggestedWords createSuggestPuncOutputTextList(final String[] puncs) {
+        final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+        if (puncs != null) {
+            for (final String puncSpec : puncs) {
+                final String outputText = MoreKeySpecParser.getOutputText(puncSpec);
+                if (outputText != null) {
+                    builder.addWord(outputText);
+                } else {
+                    builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
+                }
             }
         }
         return builder.setIsPunctuationSuggestions().build();
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index a708087..d1b808f 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -857,4 +857,59 @@
         }
         return size;
     }
+
+    public static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
+        final String text = resolveStringResource(rawText, res, packageNameResId);
+        final int size = text.length();
+        if (size == 0) {
+            return null;
+        }
+        if (size == 1) {
+            return new String[] { text };
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        ArrayList<String> list = null;
+        int start = 0;
+        for (int pos = 0; pos < size; pos++) {
+            final char c = text.charAt(pos);
+            if (c == ',') {
+                if (list == null) {
+                    list = new ArrayList<String>();
+                }
+                if (sb.length() == 0) {
+                    list.add(text.substring(start, pos));
+                } else {
+                    list.add(sb.toString());
+                    sb.setLength(0);
+                }
+                start = pos + 1;
+                continue;
+            } else if (c == ESCAPE_CHAR) {
+                if (start == pos) {
+                    // Skip escape character at the beginning of the value.
+                    start++;
+                    pos++;
+                } else {
+                    if (start < pos && sb.length() == 0) {
+                        sb.append(text.subSequence(start, pos));
+                    }
+                    pos++;
+                    if (pos < size) {
+                        sb.append(text.charAt(pos));
+                    }
+                }
+            } else if (sb.length() > 0) {
+                sb.append(c);
+            }
+        }
+        if (list == null) {
+            return new String[] {
+                    sb.length() > 0 ? sb.toString() : text.substring(start)
+            };
+        } else {
+            list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
+            return list.toArray(new String[list.size()]);
+        }
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
index 2ae8027..54a8e62 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyStylesTests.java
@@ -20,6 +20,7 @@
 import android.test.AndroidTestCase;
 import android.text.TextUtils;
 
+import com.android.inputmethod.latin.Utils;
 import com.android.inputmethod.latin.tests.R;
 
 import java.util.Arrays;
@@ -39,7 +40,7 @@
     }
 
     private void assertTextArray(String message, String value, String ... expected) {
-        final String actual[] = KeyStyles.parseCsvString(value, mTestResources,
+        final String actual[] = Utils.parseCsvString(value, mTestResources,
                 R.string.empty_string);
         if (expected.length == 0) {
             assertNull(message, actual);
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
index c689384..e9f37af 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
@@ -37,7 +37,7 @@
     // Chording input in shift locked.
     public void testChordingShiftLocked() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press shift key and hold, enter into choring shift state.
         pressKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED);
@@ -95,7 +95,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press "ABC" key, enter into chording alphabet shift locked.
@@ -112,7 +112,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press "=\<" key, enter into symbols shifted chording state.
@@ -170,7 +170,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter symbols shifted.
@@ -189,7 +189,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter symbols shifted.
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
index 55147f6..8c53fb5 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
@@ -88,7 +88,7 @@
     // Switching between alphabet shift locked and symbols.
     public void testAlphabetShiftLockedAndSymbols() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -127,7 +127,7 @@
     // Automatic switch back to alphabet shift locked test by space key.
     public void testSwitchBackBySpaceShiftLocked() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -179,7 +179,7 @@
         setLayoutSwitchBackSymbols(switchBackSymbols);
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -235,24 +235,45 @@
     }
 
     // Long press shift key.
-    // TODO: Move long press recognizing timer/logic into KeyboardState.
     public void testLongPressShift() {
+        // Set auto caps mode off.
+        setAutoCapsMode(NO_AUTO_CAPS);
+        // Load keyboard, should be in alphabet.
+        loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
-
-        // Press/release letter key, remain in shift locked.
-        pressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
-        // Press/release word separator, remain in shift locked.
-        pressAndReleaseKey(CODE_SPACE, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
-
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release shift key, back to alphabet.
         pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release letter key, remain in shift locked.
+        pressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+        // Press/release word separator, remain in shift locked.
+        pressAndReleaseKey(CODE_SPACE, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Press/release shift key, enter alphabet shifted.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Set auto caps mode on.
+        setAutoCapsMode(AUTO_CAPS);
+        // Load keyboard, should be in automatic shifted.
+        loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
     }
 
     // Double tap shift key.
@@ -311,11 +332,11 @@
         updateShiftState(ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Update shift state, remained in alphabet shift locked.
         updateShiftState(ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -342,11 +363,11 @@
         updateShiftState(ALPHABET_AUTOMATIC_SHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Update shift state, remained in alphabet shift locked (not automatic shifted).
         updateShiftState(ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Load keyboard, should be in automatic shifted.
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
@@ -393,7 +414,7 @@
 
         // Alphabet shift locked -> shift key + letter -> alphabet shift locked.
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press and slide from "123?" key, enter symbols.
         pressAndSlideFromKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Enter/release into symbol letter key, switch back to alphabet shift locked.
@@ -444,7 +465,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press and slide from "ABC" key, enter alphabet shift locked.
@@ -459,7 +480,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press and slide from "=\<" key, enter symbols shifted.
@@ -512,7 +533,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter into symbols shifted.
@@ -529,7 +550,7 @@
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter into symbols shifted.
@@ -550,7 +571,7 @@
         loadKeyboard(ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Change focus to new text field.
         loadKeyboard(ALPHABET_UNSHIFTED);
 
@@ -583,7 +604,7 @@
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Change focus to new text field.
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
 
@@ -615,7 +636,7 @@
 
         // Alphabet shift locked -> rotate -> alphabet shift locked.
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Rotate device, remain in alphabet shift locked.
         rotateDevice(ALPHABET_SHIFT_LOCKED);
 
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
index 76b8436..96a5466 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
@@ -106,15 +106,11 @@
         assertLayout(afterSlide, mSwitcher.getLayoutId());
     }
 
-    public void longPressShiftKey(int afterPress, int afterLongPress) {
-        // Long press shift key
-        mSwitcher.onPressKey(CODE_SHIFT);
-        assertLayout(afterPress, mSwitcher.getLayoutId());
-        // Long press recognized in LatinKeyboardView.KeyTimerHandler.
-        mSwitcher.onCodeInput(CODE_CAPSLOCK, SINGLE);
+    public void longPressAndReleaseKey(int code, int afterPress, int afterLongPress) {
+        pressKey(code, afterPress);
+        mSwitcher.onLongPressTimeout(code);
         assertLayout(afterLongPress, mSwitcher.getLayoutId());
-        mSwitcher.onReleaseKey(CODE_SHIFT, NOT_SLIDING);
-        assertLayout(afterLongPress, mSwitcher.getLayoutId());
+        releaseKey(code, afterLongPress);
     }
 
     public void secondPressAndReleaseKey(int code, int afterPress, int afterRelease) {
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index 2f39340..a01b69c 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -31,7 +31,6 @@
 
         public static final int CODE_SHIFT = Keyboard.CODE_SHIFT;
         public static final int CODE_SYMBOL = Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
-        public static final int CODE_CAPSLOCK = Keyboard.CODE_CAPSLOCK;
         public static final int CODE_SPACE = Keyboard.CODE_SPACE;
         public static final int CODE_AUTO_CAPS_TRIGGER = Keyboard.CODE_SPACE;
 
@@ -51,6 +50,7 @@
     private boolean mAutoCapsState = true;
 
     private boolean mIsInDoubleTapTimeout;
+    private int mLongPressTimeoutCode;
 
     private final KeyboardState mState = new KeyboardState(this);
 
@@ -129,6 +129,24 @@
         return mIsInDoubleTapTimeout;
     }
 
+    @Override
+    public void startLongPressTimer(int code) {
+        mLongPressTimeoutCode = code;
+    }
+
+    @Override
+    public void hapticAndAudioFeedback(int code) {
+        // Nothing to do.
+    }
+
+    public void onLongPressTimeout(int code) {
+        // TODO: Handle simultaneous long presses.
+        if (mLongPressTimeoutCode == code) {
+            mLongPressTimeoutCode = 0;
+            mState.onLongPressTimeout(code);
+        }
+    }
+
     public void updateShiftState() {
         mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState);
     }
@@ -147,6 +165,9 @@
 
     public void onReleaseKey(int code, boolean withSliding) {
         mState.onReleaseKey(code, withSliding);
+        if (mLongPressTimeoutCode == code) {
+            mLongPressTimeoutCode = 0;
+        }
     }
 
     public void onCodeInput(int code, boolean isSinglePointer) {