Merge "Import new drawables"
diff --git a/java/res/values-ar/donottranslate-altchars.xml b/java/res/values-ar/donottranslate-altchars.xml
new file mode 100644
index 0000000..b4c103d
--- /dev/null
+++ b/java/res/values-ar/donottranslate-altchars.xml
@@ -0,0 +1,70 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- \u060c: ARABIC COMMA
+         \u061b: ARABIC SEMICOLON
+         \u061f: ARABIC QUESTION MARK
+         \u0651: ARABIC SHADDA
+         \u0652: ARABIC SUKUN
+         \u064c: ARABIC DAMMATAN
+         \u0640: ARABIC TATWEEL
+         \u064f: ARABIC DAMMA
+         \u064e: ARABIC FATHA
+         \u0650: ARABIC KASRA
+         \u064b: ARABIC FATHATAN
+         \u064d: ARABIC KASRATAN -->
+    <string name="alternates_for_punctuation">"\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0651,\u0652,\u064c,\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
+    <string name="alternates_for_web_tab_punctuation">".,\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0651,\u0652,\u064c,\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
+    <integer name="popup_keyboard_column_for_punctuation">9</integer>
+    <integer name="popup_keyboard_column_for_web_punctuation">10</integer>
+    <string name="keyhintlabel_for_punctuation">\u064b</string>
+    <string name="keylabel_for_symbols_1">"١"</string>
+    <string name="keylabel_for_symbols_2">"٢"</string>
+    <string name="keylabel_for_symbols_3">"٣"</string>
+    <string name="keylabel_for_symbols_4">"٤"</string>
+    <string name="keylabel_for_symbols_5">"٥"</string>
+    <string name="keylabel_for_symbols_6">"٦"</string>
+    <string name="keylabel_for_symbols_7">"٧"</string>
+    <string name="keylabel_for_symbols_8">"٨"</string>
+    <string name="keylabel_for_symbols_9">"٩"</string>
+    <string name="keylabel_for_symbols_0">"٠"</string>
+    <string name="alternates_for_symbols_1">1,¹,½,⅓,¼,⅛</string>
+    <string name="alternates_for_symbols_2">2,²,⅔</string>
+    <string name="alternates_for_symbols_3">3,³,¾,⅜</string>
+    <string name="alternates_for_symbols_4">4,⁴</string>
+    <string name="alternates_for_symbols_5">5,⅝</string>
+    <string name="alternates_for_symbols_6">6</string>
+    <string name="alternates_for_symbols_7">7,⅞</string>
+    <string name="alternates_for_symbols_8">8</string>
+    <string name="alternates_for_symbols_9">9</string>
+    <string name="alternates_for_symbols_0">0,ⁿ,∅</string>
+    <string name="keylabel_for_symbols_comma">\u060c</string>
+    <string name="keylabel_for_symbols_question">\u061f</string>
+    <string name="keylabel_for_symbols_semicolon">\u061b</string>
+    <string name="alternates_for_symbols_comma">,</string>
+    <string name="alternates_for_symbols_question">\?,¿</string>
+    <string name="alternates_for_symbols_semicolon">;</string>
+    <string name="keylabel_for_apostrophe">"،"</string>
+    <string name="keylabel_for_dash">"."</string>
+    <string name="keyhintlabel_for_apostrophe">"؟"</string>
+    <string name="keyhintlabel_for_dash">"\u064b"</string>
+    <string name="alternates_for_apostrophe">"\u061f,\u061b,!,:,-,/,\',\""</string>
+    <string name="alternates_for_dash">"\u0651,\u0652,\u064c,\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
+</resources>
diff --git a/java/res/values/donottranslate-altchars.xml b/java/res/values/donottranslate-altchars.xml
index e779575..9d06d06 100644
--- a/java/res/values/donottranslate-altchars.xml
+++ b/java/res/values/donottranslate-altchars.xml
@@ -47,10 +47,46 @@
     <string name="alternates_for_currency_dollar">¢,£,€,¥,₱</string>
     <string name="alternates_for_currency_euro">¢,£,$,¥,₱</string>
     <string name="alternates_for_currency_pound">¢,$,€,¥,₱</string>
+    <string name="alternates_for_currency_general">¢,$,€,£,¥,₱</string>
     <string name="alternates_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\\\\\|:-\\\\\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
     <string name="alternates_for_punctuation">"\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
     <string name="alternates_for_web_tab_punctuation">".,\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
+    <integer name="popup_keyboard_column_for_punctuation">7</integer>
+    <integer name="popup_keyboard_column_for_web_punctuation">8</integer>
+    <string name="keyhintlabel_for_punctuation"></string>
     <string name="keylabel_for_popular_domain">".com"</string>
     <!-- popular web domains for the locale - most popular, displayed on the keyboard -->
     <string name="alternates_for_popular_domain">".net,.org,.gov,.edu"</string>
+    <string name="keylabel_for_symbols_1">1</string>
+    <string name="keylabel_for_symbols_2">2</string>
+    <string name="keylabel_for_symbols_3">3</string>
+    <string name="keylabel_for_symbols_4">4</string>
+    <string name="keylabel_for_symbols_5">5</string>
+    <string name="keylabel_for_symbols_6">6</string>
+    <string name="keylabel_for_symbols_7">7</string>
+    <string name="keylabel_for_symbols_8">8</string>
+    <string name="keylabel_for_symbols_9">9</string>
+    <string name="keylabel_for_symbols_0">0</string>
+    <string name="alternates_for_symbols_1">¹,½,⅓,¼,⅛</string>
+    <string name="alternates_for_symbols_2">²,⅔</string>
+    <string name="alternates_for_symbols_3">³,¾,⅜</string>
+    <string name="alternates_for_symbols_4">⁴</string>
+    <string name="alternates_for_symbols_5">⅝</string>
+    <string name="alternates_for_symbols_6"></string>
+    <string name="alternates_for_symbols_7">⅞</string>
+    <string name="alternates_for_symbols_8"></string>
+    <string name="alternates_for_symbols_9"></string>
+    <string name="alternates_for_symbols_0">ⁿ,∅</string>
+    <string name="keylabel_for_symbols_comma">,</string>
+    <string name="keylabel_for_symbols_question">\?</string>
+    <string name="keylabel_for_symbols_semicolon">;</string>
+    <string name="alternates_for_symbols_comma"></string>
+    <string name="alternates_for_symbols_question">¿</string>
+    <string name="alternates_for_symbols_semicolon"></string>
+    <string name="keylabel_for_apostrophe">\'</string>
+    <string name="keylabel_for_dash">-</string>
+    <string name="keyhintlabel_for_apostrophe">\"</string>
+    <string name="keyhintlabel_for_dash">_</string>
+    <string name="alternates_for_apostrophe">\"</string>
+    <string name="alternates_for_dash">_</string>
 </resources>
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index dbea4dc..388e293 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -38,7 +38,7 @@
             <key-style
                 latin:styleName="settingsPopupStyle"
                 latin:keyLabelOption="hasPopupHint"
-                latin:popupCharacters="\@icon/5|\@integer/key_settings"
+                latin:popupCharacters="\@icon/6|\@integer/key_settings"
                 latin:parentStyle="functionalKeyStyle" />
         </default>
     </switch>
@@ -50,12 +50,24 @@
         latin:keyIconShifted="iconShiftedShiftKey"
         latin:parentStyle="functionalKeyStyle"
         latin:isSticky="true" />
-    <key-style
-        latin:styleName="deleteKeyStyle"
-        latin:code="@integer/key_delete"
-        latin:keyIcon="iconDeleteKey"
-        latin:parentStyle="functionalKeyStyle"
-        latin:isRepeatable="true" />
+    <switch>
+        <case latin:languageCode="ar|iw">
+            <key-style
+                latin:styleName="deleteKeyStyle"
+                latin:code="@integer/key_delete"
+                latin:keyIcon="iconDeleteRtlKey"
+                latin:parentStyle="functionalKeyStyle"
+                latin:isRepeatable="true" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="deleteKeyStyle"
+                latin:code="@integer/key_delete"
+                latin:keyIcon="iconDeleteKey"
+                latin:parentStyle="functionalKeyStyle"
+                latin:isRepeatable="true" />
+        </default>
+    </switch>
     <key-style
         latin:styleName="returnKeyStyle"
         latin:code="@integer/key_return"
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row3.xml b/java/res/xml-sw600dp/kbd_qwerty_row3.xml
index 278db13..b4eed8a 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row3.xml
@@ -46,29 +46,9 @@
             latin:popupCharacters="@string/alternates_for_n" />
         <Key
             latin:keyLabel="m" />
-        <switch>
-            <case
-                latin:mode="email"
-            >
-                <Key
-                    latin:keyLabel="," />
-                <Key
-                    latin:keyLabel="." />
-            </case>
-            <default>
-                <Key
-                    latin:keyLabel=","
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="!"
-                    latin:popupCharacters="!" />
-                <Key
-                    latin:keyLabel="."
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="\?"
-                    latin:popupCharacters="\?" />
-            </default>
-        </switch>
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+        <include
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row4.xml b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
index 4f41c17..5cd47d9 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
@@ -59,99 +59,15 @@
             latin:keyWidth="39.750%p" />
         <switch>
             <case
-                latin:languageCode="ru"
+                latin:languageCode="iw"
             >
-                <switch>
-                    <case
-                        latin:mode="email"
-                    >
-                        <Key
-                            latin:keyLabel="-"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <case
-                        latin:mode="url"
-                    >
-                        <Key
-                            latin:keyLabel="/"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel=":"
-                            latin:popupCharacters=":"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="\?"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel="_"
-                            latin:popupCharacters="_"
-                            latin:keyWidth="9.750%p" />
-                    </default>
-                </switch>
-                <switch>
-                    <case
-                        latin:mode="email"
-                    >
-                        <Key
-                            latin:keyLabel="_"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="!"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel="\'"
-                            latin:popupCharacters="\'"
-                            latin:keyWidth="9.750%p" />
-                    </default>
-                </switch>
+                <include
+                    latin:keyboardLayout="@xml/kbd_row3_comma_period" />
             </case>
-            <!-- not languageCode="ru" -->
+            <!-- not languageCode="iw" -->
             <default>
-                <switch>
-                    <case
-                        latin:mode="email"
-                    >
-                        <Key
-                            latin:keyLabel="-"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <case
-                        latin:mode="url"
-                    >
-                        <Key
-                            latin:keyLabel="/"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel=":"
-                            latin:popupCharacters=":"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="\'"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel="&quot;"
-                            latin:popupCharacters="&quot;"
-                            latin:keyWidth="9.750%p" />
-                    </default>
-                </switch>
-                <switch>
-                    <case
-                        latin:mode="email"
-                    >
-                        <Key
-                            latin:keyLabel="_"
-                            latin:keyWidth="9.750%p" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="-"
-                            latin:keyLabelOption="hasUppercaseLetter"
-                            latin:keyHintLabel="_"
-                            latin:popupCharacters="_"
-                            latin:keyWidth="9.750%p" />
-                    </default>
-                </switch>
+                <include
+                    latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
             </default>
         </switch>
         <Spacer
diff --git a/java/res/xml-sw768dp/kbd_row3_right2.xml b/java/res/xml-sw600dp/kbd_row3_comma_period.xml
similarity index 100%
copy from java/res/xml-sw768dp/kbd_row3_right2.xml
copy to java/res/xml-sw600dp/kbd_row3_comma_period.xml
diff --git a/java/res/xml-sw600dp/kbd_row3_right.xml b/java/res/xml-sw600dp/kbd_row3_smiley.xml
similarity index 100%
rename from java/res/xml-sw600dp/kbd_row3_right.xml
rename to java/res/xml-sw600dp/kbd_row3_smiley.xml
diff --git a/java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml b/java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml
new file mode 100644
index 0000000..50d4d4b
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:mode="email"
+        >
+            <Key
+                latin:keyLabel="-" />
+        </case>
+        <case
+            latin:mode="url"
+        >
+            <Key
+                latin:keyLabel="/"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel=":"
+                latin:popupCharacters=":" />
+        </case>
+        <default>
+            <Key
+                latin:keyLabel="@string/keylabel_for_apostrophe"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel="@string/keyhintlabel_for_apostrophe"
+                latin:popupCharacters="@string/alternates_for_apostrophe" />
+        </default>
+    </switch>
+    <switch>
+        <case
+            latin:mode="email"
+        >
+            <Key
+                latin:keyLabel="_" />
+        </case>
+        <default>
+            <Key
+                latin:keyLabel="@string/keylabel_for_dash"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel="@string/keyhintlabel_for_dash"
+                latin:popupCharacters="@string/alternates_for_dash" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_arabic.xml b/java/res/xml-sw600dp/kbd_rows_arabic.xml
index bc37d5a..4c19094 100644
--- a/java/res/xml-sw600dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw600dp/kbd_rows_arabic.xml
@@ -18,9 +18,6 @@
 */
 -->
 
-<!-- This file for Arabic layout is an alpha version. It allows to enter   -->
-<!-- some right-to-left text, but it has gone through no study whatsoever, -->
-<!-- and needs to be run through UX.                                       -->
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
@@ -40,21 +37,23 @@
             latin:keyLabel="ق" />
         <Key
             latin:keyLabel="ف"
-            latin:popupCharacters="ف,ڤ" />
+            latin:popupCharacters="ڤ" />
         <Key
             latin:keyLabel="غ" />
         <Key
             latin:keyLabel="ع" />
+        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
+             \u0647\u0640: ARABIC LETTER HEH + ARABIC TATWEEL -->
         <Key
             latin:keyLabel="ه"
-            latin:popupCharacters="ه,هـ" />
+            latin:popupCharacters="\ufeeb|\u0647\u0640" />
         <Key
             latin:keyLabel="خ" />
         <Key
             latin:keyLabel="ح" />
         <Key
             latin:keyLabel="ج"
-            latin:popupCharacters="ج,چ" />
+            latin:popupCharacters="چ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyXPos="-10.0%p"
@@ -73,13 +72,25 @@
             latin:keyLabel="ي" />
         <Key
             latin:keyLabel="ب"
-            latin:popupCharacters="ب,پ" />
+            latin:popupCharacters="پ" />
+        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+             \u0644: ARABIC LETTER LAM
+             \u0627: ARABIC LETTER ALEF
+             \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+             \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \ufef9: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \ufef5: ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ل"
-            latin:popupCharacters="ل,لا" />
+            latin:popupCharacters="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
+        <!-- \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ا"
-            latin:popupCharacters="ا,أ,إ,آ" />
+            latin:popupCharacters="\u0623,\u0625,\u0622" />
         <Key
             latin:keyLabel="ت" />
         <Key
@@ -88,7 +99,7 @@
             latin:keyLabel="م" />
         <Key
             latin:keyLabel="ك"
-            latin:popupCharacters="ك,گ" />
+            latin:popupCharacters="گ" />
         <Key
             latin:keyLabel="ط" />
         <Key
@@ -98,12 +109,43 @@
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="7.65%p"
+        latin:keyWidth="8.0%p"
     >
-        <Key
-            latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="8.0%p"
-            latin:keyEdgeFlags="left" />
+    <!-- kbd_row3_smiley -->
+        <switch>
+            <case
+                latin:mode="email"
+            >
+                <Key
+                    latin:keyLabel="\@"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <case
+                latin:mode="url"
+            >
+                <Key
+                    latin:keyLabel="-"
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="_"
+                    latin:popupCharacters="_"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <case
+                latin:imeAction="actionSearch"
+            >
+                <Key
+                    latin:keyLabel=":"
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="+"
+                    latin:popupCharacters="+"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <default>
+                <Key
+                    latin:keyStyle="smileyKeyStyle"
+                    latin:keyEdgeFlags="left" />
+            </default>
+        </switch>
         <Key
             latin:keyLabel="ئ" />
         <Key
@@ -122,13 +164,12 @@
             latin:keyLabel="و" />
         <Key
             latin:keyLabel="ز"
-            latin:popupCharacters="ز,ژ" />
+            latin:popupCharacters="ژ" />
         <Key
             latin:keyLabel="ظ" />
         <Key
             latin:keyLabel="د" />
-        <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
-        </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_azerty.xml b/java/res/xml-sw600dp/kbd_rows_azerty.xml
index 7ba716b..698ef22 100644
--- a/java/res/xml-sw600dp/kbd_rows_azerty.xml
+++ b/java/res/xml-sw600dp/kbd_rows_azerty.xml
@@ -149,7 +149,7 @@
             </default>
         </switch>
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw600dp/kbd_rows_hebrew.xml b/java/res/xml-sw600dp/kbd_rows_hebrew.xml
index a147537..8740915 100644
--- a/java/res/xml-sw600dp/kbd_rows_hebrew.xml
+++ b/java/res/xml-sw600dp/kbd_rows_hebrew.xml
@@ -24,13 +24,11 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.600%p"
+        latin:keyWidth="9.0%p"
         latin:rowEdgeFlags="top"
     >
-        <Key
-            latin:keyLabel="," />
-        <Key
-            latin:keyLabel="." />
+        <include
+            latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
         <Key
             latin:keyLabel="ק" />
         <Key
@@ -54,48 +52,78 @@
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.600%p"
+        latin:keyWidth="9.0%p"
     >
         <Key
             latin:keyLabel="ש"
-            latin:keyXPos="4.000%p" />
+            latin:keyXPos="4.500%p" />
         <Key
             latin:keyLabel="ד" />
         <Key
             latin:keyLabel="ג"
-            latin:popupCharacters="ג,ג׳" />
+            latin:popupCharacters="ג׳" />
         <Key
             latin:keyLabel="כ" />
         <Key
             latin:keyLabel="ע" />
         <Key
             latin:keyLabel="י"
-            latin:popupCharacters="י,ײַ" />
+            latin:popupCharacters="ײַ" />
         <Key
             latin:keyLabel="ח"
-            latin:popupCharacters="ח,ח׳" />
+            latin:popupCharacters="ח׳" />
         <Key
             latin:keyLabel="ל" />
         <Key
             latin:keyLabel="ך" />
         <Key
             latin:keyLabel="ף" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-10.400%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.600%p"
+        latin:keyWidth="8.9%p"
     >
-        <Key
-            latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="10.000%p"
-            latin:keyEdgeFlags="left" />
+        <!-- kbd_row3_smiley -->
+        <switch>
+            <case
+                latin:mode="email"
+            >
+                <Key
+                    latin:keyLabel="\@"
+                    latin:keyWidth="10.0%p"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <case
+                latin:mode="url"
+            >
+                <Key
+                    latin:keyLabel="-"
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="_"
+                    latin:popupCharacters="_"
+                    latin:keyWidth="10.0%p"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <case
+                latin:imeAction="actionSearch"
+            >
+                <Key
+                    latin:keyLabel=":"
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="+"
+                    latin:popupCharacters="+"
+                    latin:keyWidth="10.0%p"
+                    latin:keyEdgeFlags="left" />
+            </case>
+            <default>
+                <Key
+                    latin:keyStyle="smileyKeyStyle"
+                    latin:keyWidth="10.0%p"
+                    latin:keyEdgeFlags="left" />
+            </default>
+        </switch>
         <Key
             latin:keyLabel="ז"
-            latin:popupCharacters="ז,ז׳" />
+            latin:popupCharacters="ז׳" />
         <Key
             latin:keyLabel="ס" />
         <Key
@@ -108,15 +136,19 @@
             latin:keyLabel="מ" />
         <Key
             latin:keyLabel="צ"
-            latin:popupCharacters="צ,צ׳" />
+            latin:popupCharacters="צ׳" />
         <Key
             latin:keyLabel="ת"
-            latin:popupCharacters="ת,ת׳" />
+            latin:popupCharacters="ת׳" />
         <Key
             latin:keyLabel="ץ"
-            latin:popupCharacters="ץ,ץ׳" />
-        <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:popupCharacters="ץ׳" />
+        <Key
+            latin:keyStyle="returnKeyStyle"
+            latin:keyXPos="-10.400%p"
+            latin:keyWidth="fillBoth"
+            latin:keyEdgeFlags="right" />
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_qwertz.xml b/java/res/xml-sw600dp/kbd_rows_qwertz.xml
index 7f85fe7..7ec895e 100644
--- a/java/res/xml-sw600dp/kbd_rows_qwertz.xml
+++ b/java/res/xml-sw600dp/kbd_rows_qwertz.xml
@@ -114,7 +114,7 @@
             </default>
         </switch>
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw600dp/kbd_rows_russian.xml b/java/res/xml-sw600dp/kbd_rows_russian.xml
index b723247..4452989 100644
--- a/java/res/xml-sw600dp/kbd_rows_russian.xml
+++ b/java/res/xml-sw600dp/kbd_rows_russian.xml
@@ -24,12 +24,11 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.0%p"
+        latin:keyWidth="7.60%p"
         latin:rowEdgeFlags="top"
     >
         <Key
             latin:keyLabel="й"
-            latin:keyXPos="2.15%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ц" />
@@ -53,17 +52,19 @@
         <Key
             latin:keyLabel="х" />
         <Key
+            latin:keyLabel="ъ" />
+        <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyXPos="-10.0%p"
             latin:keyWidth="fillBoth"
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-            latin:keyWidth="8.0%p"
+        latin:keyWidth="7.60%p"
     >
         <Key
             latin:keyLabel="ф"
-            latin:keyEdgeFlags="left" />
+            latin:keyXPos="2.25%p" />
         <Key
             latin:keyLabel="ы" />
         <Key
@@ -91,11 +92,10 @@
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.0%p"
+        latin:keyWidth="7.60%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="10.0%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="я" />
@@ -116,13 +116,30 @@
             latin:keyLabel="б" />
         <Key
             latin:keyLabel="ю" />
-        <Key
-            latin:keyLabel="."
-            latin:keyLabelOption="hasUppercaseLetter"
-            latin:keyHintLabel=","
-            latin:popupCharacters="," />
+        <switch>
+            <case
+                latin:mode="email"
+            >
+                <Key
+                    latin:keyLabel="," />
+                <Key
+                    latin:keyLabel="." />
+            </case>
+            <default>
+                <Key
+                    latin:keyLabel=","
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="!"
+                    latin:popupCharacters="!" />
+                <Key
+                    latin:keyLabel="."
+                    latin:keyLabelOption="hasUppercaseLetter"
+                    latin:keyHintLabel="\?"
+                    latin:popupCharacters="\?" />
+            </default>
+        </switch>
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw600dp/kbd_rows_scandinavian.xml b/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
index 645ef62..5ac2b36 100644
--- a/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
+++ b/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
@@ -134,32 +134,12 @@
             latin:popupCharacters="@string/alternates_for_n" />
         <Key
             latin:keyLabel="m" />
-        <switch>
-            <case
-                latin:mode="email"
-            >
-                <Key
-                    latin:keyLabel="," />
-                <Key
-                    latin:keyLabel="." />
-            </case>
-            <default>
-                <Key
-                    latin:keyLabel=","
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="!"
-                    latin:popupCharacters="!" />
-                <Key
-                    latin:keyLabel="."
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="\?"
-                    latin:popupCharacters="\?" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
         <Spacer
             latin:keyWidth="4.35%p" />
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw600dp/kbd_rows_serbian.xml b/java/res/xml-sw600dp/kbd_rows_serbian.xml
index 4dfe944..5d39fd4 100644
--- a/java/res/xml-sw600dp/kbd_rows_serbian.xml
+++ b/java/res/xml-sw600dp/kbd_rows_serbian.xml
@@ -114,30 +114,10 @@
             latin:keyLabel="ђ" />
         <Key
             latin:keyLabel="ж" />
-        <switch>
-            <case
-                latin:mode="email"
-            >
-                <Key
-                    latin:keyLabel="," />
-                <Key
-                    latin:keyLabel="." />
-            </case>
-            <default>
-                <Key
-                    latin:keyLabel=","
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="!"
-                    latin:popupCharacters="!" />
-                <Key
-                    latin:keyLabel="."
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="\?"
-                    latin:popupCharacters="\?" />
-            </default>
-        </switch>
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+        <include
+            latin:keyboardLayout="@xml/kbd_row3_smiley" />
     </Row>
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_row4" />
diff --git a/java/res/xml-sw600dp/kbd_symbols.xml b/java/res/xml-sw600dp/kbd_symbols.xml
index 77849f6..dea08dd 100644
--- a/java/res/xml-sw600dp/kbd_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_symbols.xml
@@ -30,32 +30,36 @@
         latin:keyWidth="9.0%p"
     >
         <Key
-            latin:keyLabel="1"
-            latin:popupCharacters="¹,½,⅓,¼,⅛" />
+            latin:keyLabel="@string/keylabel_for_symbols_1"
+            latin:popupCharacters="@string/alternates_for_symbols_1"
+            latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="2"
-            latin:popupCharacters="²,⅔" />
+            latin:keyLabel="@string/keylabel_for_symbols_2"
+            latin:popupCharacters="@string/alternates_for_symbols_2" />
         <Key
-            latin:keyLabel="3"
-            latin:popupCharacters="³,¾,⅜" />
+            latin:keyLabel="@string/keylabel_for_symbols_3"
+            latin:popupCharacters="@string/alternates_for_symbols_3" />
         <Key
-            latin:keyLabel="4"
-            latin:popupCharacters="⁴" />
+            latin:keyLabel="@string/keylabel_for_symbols_4"
+            latin:popupCharacters="@string/alternates_for_symbols_4" />
         <Key
-            latin:keyLabel="5"
-            latin:popupCharacters="⅝" />
+            latin:keyLabel="@string/keylabel_for_symbols_5"
+            latin:popupCharacters="@string/alternates_for_symbols_5" />
         <Key
-            latin:keyLabel="6" />
+            latin:keyLabel="@string/keylabel_for_symbols_6"
+            latin:popupCharacters="@string/alternates_for_symbols_6" />
         <Key
-            latin:keyLabel="7"
-            latin:popupCharacters="⅞" />
+            latin:keyLabel="@string/keylabel_for_symbols_7"
+            latin:popupCharacters="@string/alternates_for_symbols_7" />
         <Key
-            latin:keyLabel="8" />
+            latin:keyLabel="@string/keylabel_for_symbols_8"
+            latin:popupCharacters="@string/alternates_for_symbols_8" />
         <Key
-            latin:keyLabel="9" />
+            latin:keyLabel="@string/keylabel_for_symbols_9"
+            latin:popupCharacters="@string/alternates_for_symbols_9" />
         <Key
-            latin:keyLabel="0"
-            latin:popupCharacters="ⁿ,∅" />
+            latin:keyLabel="@string/keylabel_for_symbols_0"
+            latin:popupCharacters="@string/alternates_for_symbols_0" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyXPos="-10.0%p"
@@ -114,12 +118,6 @@
             latin:popupCharacters="≠,≈" />
         <switch>
             <case
-                latin:languageCode="ru"
-            >
-                <Key
-                    latin:keyLabel=":" />
-            </case>
-            <case
                 latin:mode="url"
             >
                 <Key
@@ -132,38 +130,19 @@
             </default>
         </switch>
         <Key
-            latin:keyLabel=";" />
-        <switch>
-            <case
-                latin:languageCode="ru"
-            >
-                <Key
-                    latin:keyLabel="\'"
-                    latin:popupCharacters="‘,’,‚,‛" />
-                <!-- Note: DroidSans doesn't have double-high-reversed-quotation
-                    '\u201f' glyph. -->
-                <!-- latin:popupCharacters="“,”,„,‟,«,»" -->
-                <Key
-                    latin:keyLabel="&quot;"
-                    latin:popupCharacters="“,”,«,»" />
-                <Key
-                    latin:keyLabel="." />
-                <Key
-                    latin:keyLabel="," />
-            </case>
-            <default>
-                <Key
-                    latin:keyLabel="," />
-                <Key
-                    latin:keyLabel="." />
-                <Key
-                    latin:keyLabel="!"
-                    latin:popupCharacters="¡" />
-                <Key
-                    latin:keyLabel="\?"
-                    latin:popupCharacters="¿" />
-            </default>
-        </switch>
+            latin:keyLabel="@string/keylabel_for_symbols_semicolon"
+            latin:popupCharacters="@string/alternates_for_symbols_semicolon" />
+        <Key
+            latin:keyLabel="@string/keylabel_for_symbols_comma"
+            latin:popupCharacters="@string/alternates_for_symbols_comma" />
+        <Key
+            latin:keyLabel="." />
+        <Key
+            latin:keyLabel="!"
+            latin:popupCharacters="¡" />
+        <Key
+            latin:keyLabel="@string/keylabel_for_symbols_question"
+            latin:popupCharacters="@string/alternates_for_symbols_question" />
         <Key
             latin:keyLabel="/"
             latin:keyWidth="fillRight" />
@@ -185,30 +164,13 @@
             latin:keyStyle="spaceKeyStyle"
             latin:keyXPos="30.750%p"
             latin:keyWidth="39.750%p" />
-        <switch>
-            <case
-                latin:languageCode="ru"
-            >
-                <Key
-                    latin:keyLabel="_"
-                    latin:keyWidth="9.750%p" />
-                <Key
-                    latin:keyLabel="-"
-                    latin:keyWidth="9.750%p" />
-            </case>
-            <default>
-                <!-- Note: DroidSans doesn't have double-high-reversed-quotation
-                    '\u201f' glyph. -->
-                <!-- latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" -->
-                <Key
-                    latin:keyLabel="&quot;"
-                    latin:popupCharacters="“,”,«,»,‘,’,‚,‛"
-                    latin:keyWidth="9.750%p" />
-                <Key
-                    latin:keyLabel="_"
-                    latin:keyWidth="9.750%p" />
-            </default>
-        </switch>
+        <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
+        <!-- latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" -->
+        <Key
+            latin:keyLabel="&quot;"
+            latin:popupCharacters="“,”,«,»,‘,’,‚,‛" />
+        <Key
+            latin:keyLabel="_" />
         <Spacer
             latin:keyXPos="-10.00%p"
             latin:keyWidth="0%p" />
diff --git a/java/res/xml-sw768dp/kbd_key_styles.xml b/java/res/xml-sw768dp/kbd_key_styles.xml
index 4c1e3b6..ab8784a 100644
--- a/java/res/xml-sw768dp/kbd_key_styles.xml
+++ b/java/res/xml-sw768dp/kbd_key_styles.xml
@@ -32,12 +32,24 @@
         latin:keyIconShifted="iconShiftedShiftKey"
         latin:parentStyle="functionalKeyStyle"
         latin:isSticky="true" />
-    <key-style
-        latin:styleName="deleteKeyStyle"
-        latin:code="@integer/key_delete"
-        latin:keyIcon="iconDeleteKey"
-        latin:parentStyle="functionalKeyStyle"
-        latin:isRepeatable="true" />
+    <switch>
+        <case latin:languageCode="ar|iw">
+            <key-style
+                latin:styleName="deleteKeyStyle"
+                latin:code="@integer/key_delete"
+                latin:keyIcon="iconDeleteRtlKey"
+                latin:parentStyle="functionalKeyStyle"
+                latin:isRepeatable="true" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="deleteKeyStyle"
+                latin:code="@integer/key_delete"
+                latin:keyIcon="iconDeleteKey"
+                latin:parentStyle="functionalKeyStyle"
+                latin:isRepeatable="true" />
+        </default>
+    </switch>
     <key-style
         latin:styleName="returnKeyStyle"
         latin:code="@integer/key_return"
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row3.xml b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
index 7297ea5..9041a77 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
@@ -47,7 +47,7 @@
         <Key
             latin:keyLabel="m" />
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right2" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
         <Key
             latin:keyStyle="shiftKeyStyle"
             latin:keyXPos="-13.750%p"
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
index bdef89d..48201c9 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
@@ -90,41 +90,14 @@
             latin:keyWidth="37.500%p" />
         <switch>
             <case
-                latin:mode="email"
+                latin:languageCode="iw"
             >
-                <Key
-                    latin:keyLabel="-" />
-            </case>
-            <case
-                latin:mode="url"
-            >
-                <Key
-                    latin:keyLabel="/"
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel=":"
-                    latin:popupCharacters=":" />
+                <include
+                    latin:keyboardLayout="@xml/kbd_row3_comma_period" />
             </case>
             <default>
-                <Key
-                    latin:keyLabel="\'"
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="&quot;"
-                    latin:popupCharacters="&quot;" />
-            </default>
-        </switch>
-        <switch>
-            <case
-                latin:mode="email"
-            >
-                <Key
-                    latin:keyLabel="_" />
-            </case>
-            <default>
-                <Key
-                    latin:keyLabel="-"
-                    latin:keyLabelOption="hasUppercaseLetter"
-                    latin:keyHintLabel="_"
-                    latin:popupCharacters="_" />
+                <include
+                    latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
             </default>
         </switch>
         <switch>
diff --git a/java/res/xml-sw768dp/kbd_row3_right2.xml b/java/res/xml-sw768dp/kbd_row3_comma_period.xml
similarity index 100%
rename from java/res/xml-sw768dp/kbd_row3_right2.xml
rename to java/res/xml-sw768dp/kbd_row3_comma_period.xml
diff --git a/java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml b/java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml
new file mode 100644
index 0000000..50d4d4b
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:mode="email"
+        >
+            <Key
+                latin:keyLabel="-" />
+        </case>
+        <case
+            latin:mode="url"
+        >
+            <Key
+                latin:keyLabel="/"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel=":"
+                latin:popupCharacters=":" />
+        </case>
+        <default>
+            <Key
+                latin:keyLabel="@string/keylabel_for_apostrophe"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel="@string/keyhintlabel_for_apostrophe"
+                latin:popupCharacters="@string/alternates_for_apostrophe" />
+        </default>
+    </switch>
+    <switch>
+        <case
+            latin:mode="email"
+        >
+            <Key
+                latin:keyLabel="_" />
+        </case>
+        <default>
+            <Key
+                latin:keyLabel="@string/keylabel_for_dash"
+                latin:keyLabelOption="hasUppercaseLetter"
+                latin:keyHintLabel="@string/keyhintlabel_for_dash"
+                latin:popupCharacters="@string/alternates_for_dash" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_arabic.xml b/java/res/xml-sw768dp/kbd_rows_arabic.xml
index c181002..f3283ae 100644
--- a/java/res/xml-sw768dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw768dp/kbd_rows_arabic.xml
@@ -18,9 +18,6 @@
 */
 -->
 
-<!-- This file for Arabic layout is an alpha version. It allows to enter   -->
-<!-- some right-to-left text, but it has gone through no study whatsoever, -->
-<!-- and needs to be run through UX.                                       -->
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
@@ -44,21 +41,23 @@
             latin:keyLabel="ق" />
         <Key
             latin:keyLabel="ف"
-            latin:popupCharacters="ف,ڤ" />
+            latin:popupCharacters="ڤ" />
         <Key
             latin:keyLabel="غ" />
         <Key
             latin:keyLabel="ع" />
+        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
+             \u0647\u0640: ARABIC LETTER HEH + ARABIC TATWEEL -->
         <Key
             latin:keyLabel="ه"
-            latin:popupCharacters="ه,هـ" />
+            latin:popupCharacters="\ufeeb|\u0647\u0640" />
         <Key
             latin:keyLabel="خ" />
         <Key
             latin:keyLabel="ح" />
         <Key
             latin:keyLabel="ج"
-            latin:popupCharacters="ج,چ" />
+            latin:popupCharacters="چ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyXPos="-11.500%p"
@@ -81,13 +80,25 @@
             latin:keyLabel="ي" />
         <Key
             latin:keyLabel="ب"
-            latin:popupCharacters="ب,پ" />
+            latin:popupCharacters="پ" />
+        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+             \u0644: ARABIC LETTER LAM
+             \u0627: ARABIC LETTER ALEF
+             \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+             \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \ufef9: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \ufef5: ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ل"
-            latin:popupCharacters="ل,لا" />
+            latin:popupCharacters="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
+        <!-- \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ا"
-            latin:popupCharacters="ا,أ,إ,آ" />
+            latin:popupCharacters="\u0623,\u0625,\u0622" />
         <Key
             latin:keyLabel="ت" />
         <Key
@@ -96,7 +107,7 @@
             latin:keyLabel="م" />
         <Key
             latin:keyLabel="ك"
-            latin:popupCharacters="ك,گ" />
+            latin:popupCharacters="گ" />
         <Key
             latin:keyLabel="ط" />
         <Key
@@ -109,11 +120,8 @@
         latin:keyWidth="7.375%p"
     >
         <Key
-            latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="12.750%p"
-            latin:keyEdgeFlags="left" />
-        <Key
-            latin:keyLabel="ئ" />
+            latin:keyLabel="ئ"
+            latin:keyXPos="12.750%p" />
         <Key
             latin:keyLabel="ء" />
         <Key
@@ -130,11 +138,12 @@
             latin:keyLabel="و" />
         <Key
             latin:keyLabel="ز"
-            latin:popupCharacters="ز,ژ" />
+            latin:popupCharacters="ژ" />
         <Key
             latin:keyLabel="ظ" />
         <Key
             latin:keyLabel="د" />
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_hebrew.xml b/java/res/xml-sw768dp/kbd_rows_hebrew.xml
index 5275a1f..0ef68b6 100644
--- a/java/res/xml-sw768dp/kbd_rows_hebrew.xml
+++ b/java/res/xml-sw768dp/kbd_rows_hebrew.xml
@@ -24,16 +24,15 @@
     <include
         latin:keyboardLayout="@xml/kbd_key_styles" />
     <Row
-        latin:keyWidth="8.000%p"
+        latin:keyWidth="8.282%p"
     >
         <Key
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
+            latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
-        <Key
-            latin:keyLabel="," />
-        <Key
-            latin:keyLabel="." />
+        <include
+            latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
         <Key
             latin:keyLabel="ק" />
         <Key
@@ -57,12 +56,12 @@
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.000%p"
+        latin:keyWidth="8.125%p"
     >
         <Key
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
-            latin:keyWidth="9.600%p"
+            latin:keyWidth="11.172%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ש" />
@@ -70,39 +69,31 @@
             latin:keyLabel="ד" />
         <Key
             latin:keyLabel="ג"
-            latin:popupCharacters="ג,ג׳" />
+            latin:popupCharacters="ג׳" />
         <Key
             latin:keyLabel="כ" />
         <Key
             latin:keyLabel="ע" />
         <Key
             latin:keyLabel="י"
-            latin:popupCharacters="י,ײַ" />
+            latin:popupCharacters="ײַ" />
         <Key
             latin:keyLabel="ח"
-            latin:popupCharacters="ח,ח׳" />
+            latin:popupCharacters="ח׳" />
         <Key
             latin:keyLabel="ל" />
         <Key
             latin:keyLabel="ך" />
         <Key
             latin:keyLabel="ף" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-10.400%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="8.000%p"
+        latin:keyWidth="8.047%p"
     >
         <Key
-            latin:keyStyle="shiftKeyStyle"
-            latin:keyWidth="13.200%p"
-            latin:keyEdgeFlags="left" />
-        <Key
             latin:keyLabel="ז"
-            latin:popupCharacters="ז,ז׳" />
+            latin:popupCharacters="ז׳"
+            latin:keyXPos="13.829%p" />
         <Key
             latin:keyLabel="ס" />
         <Key
@@ -115,13 +106,19 @@
             latin:keyLabel="מ" />
         <Key
             latin:keyLabel="צ"
-            latin:popupCharacters="צ,צ׳" />
+            latin:popupCharacters="צ׳" />
         <Key
             latin:keyLabel="ת"
-            latin:popupCharacters="ת,ת׳" />
+            latin:popupCharacters="ת׳" />
         <Key
             latin:keyLabel="ץ"
-            latin:popupCharacters="ץ,ץ׳" />
+            latin:popupCharacters="ץ׳" />
+        <Key
+            latin:keyStyle="returnKeyStyle"
+            latin:keyXPos="-10.400%p"
+            latin:keyWidth="fillBoth"
+            latin:keyEdgeFlags="right" />
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_russian.xml b/java/res/xml-sw768dp/kbd_rows_russian.xml
index ee91481..35b2c8a 100644
--- a/java/res/xml-sw768dp/kbd_rows_russian.xml
+++ b/java/res/xml-sw768dp/kbd_rows_russian.xml
@@ -123,7 +123,7 @@
         <Key
             latin:keyLabel="ю" />
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right2" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
         <Key
             latin:keyStyle="shiftKeyStyle"
             latin:keyWidth="fillBoth"
diff --git a/java/res/xml-sw768dp/kbd_rows_scandinavian.xml b/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
index 7e9f604..c20dcee 100644
--- a/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
+++ b/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
@@ -139,7 +139,7 @@
         <Key
             latin:keyLabel="m" />
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right2" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
         <Key
             latin:keyStyle="shiftKeyStyle"
             latin:keyXPos="-12.750%p"
diff --git a/java/res/xml-sw768dp/kbd_rows_serbian.xml b/java/res/xml-sw768dp/kbd_rows_serbian.xml
index 4997dab..f1576de 100644
--- a/java/res/xml-sw768dp/kbd_rows_serbian.xml
+++ b/java/res/xml-sw768dp/kbd_rows_serbian.xml
@@ -118,7 +118,7 @@
         <Key
             latin:keyLabel="м" />
         <include
-            latin:keyboardLayout="@xml/kbd_row3_right2" />
+            latin:keyboardLayout="@xml/kbd_row3_comma_period" />
         <Key
             latin:keyStyle="returnKeyStyle"
             latin:keyXPos="-13.750%p"
diff --git a/java/res/xml-sw768dp/kbd_symbols.xml b/java/res/xml-sw768dp/kbd_symbols.xml
index 0e6103a..eb77d4d 100644
--- a/java/res/xml-sw768dp/kbd_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_symbols.xml
@@ -35,32 +35,35 @@
             latin:keyWidth="7.969%p"
             latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="1"
-            latin:popupCharacters="¹,½,⅓,¼,⅛" />
+            latin:keyLabel="@string/keylabel_for_symbols_1"
+            latin:popupCharacters="@string/alternates_for_symbols_1" />
         <Key
-            latin:keyLabel="2"
-            latin:popupCharacters="²,⅔" />
+            latin:keyLabel="@string/keylabel_for_symbols_2"
+            latin:popupCharacters="@string/alternates_for_symbols_2" />
         <Key
-            latin:keyLabel="3"
-            latin:popupCharacters="³,¾,⅜" />
+            latin:keyLabel="@string/keylabel_for_symbols_3"
+            latin:popupCharacters="@string/alternates_for_symbols_3" />
         <Key
-            latin:keyLabel="4"
-            latin:popupCharacters="⁴" />
+            latin:keyLabel="@string/keylabel_for_symbols_4"
+            latin:popupCharacters="@string/alternates_for_symbols_4" />
         <Key
-            latin:keyLabel="5"
-            latin:popupCharacters="⅝" />
+            latin:keyLabel="@string/keylabel_for_symbols_5"
+            latin:popupCharacters="@string/alternates_for_symbols_5" />
         <Key
-            latin:keyLabel="6" />
+            latin:keyLabel="@string/keylabel_for_symbols_6"
+            latin:popupCharacters="@string/alternates_for_symbols_6" />
         <Key
-            latin:keyLabel="7"
-            latin:popupCharacters="⅞" />
+            latin:keyLabel="@string/keylabel_for_symbols_7"
+            latin:popupCharacters="@string/alternates_for_symbols_7" />
         <Key
-            latin:keyLabel="8" />
+            latin:keyLabel="@string/keylabel_for_symbols_8"
+            latin:popupCharacters="@string/alternates_for_symbols_8" />
         <Key
-            latin:keyLabel="9" />
+            latin:keyLabel="@string/keylabel_for_symbols_9"
+            latin:popupCharacters="@string/alternates_for_symbols_9" />
         <Key
-            latin:keyLabel="0"
-            latin:popupCharacters="ⁿ,∅" />
+            latin:keyLabel="@string/keylabel_for_symbols_0"
+            latin:popupCharacters="@string/alternates_for_symbols_0" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyXPos="-9.219%p"
@@ -135,17 +138,19 @@
             </default>
         </switch>
         <Key
-            latin:keyLabel=";" />
+            latin:keyLabel="@string/keylabel_for_symbols_semicolon"
+            latin:popupCharacters="@string/alternates_for_symbols_semicolon" />
         <Key
-            latin:keyLabel="," />
+            latin:keyLabel="@string/keylabel_for_symbols_comma"
+            latin:popupCharacters="@string/alternates_for_symbols_comma" />
         <Key
             latin:keyLabel="." />
         <Key
             latin:keyLabel="!"
             latin:popupCharacters="¡" />
         <Key
-            latin:keyLabel="\?"
-            latin:popupCharacters="¿" />
+            latin:keyLabel="@string/keylabel_for_symbols_question"
+            latin:popupCharacters="@string/alternates_for_symbols_question" />
         <Key
             latin:keyStyle="moreKeyStyle"
             latin:keyXPos="-13.750%p"
diff --git a/java/res/xml/kbd_currency_key_styles.xml b/java/res/xml/kbd_currency_key_styles.xml
index 9d3bb47..d2c7117 100644
--- a/java/res/xml/kbd_currency_key_styles.xml
+++ b/java/res/xml/kbd_currency_key_styles.xml
@@ -80,6 +80,14 @@
                 latin:keyLabel="€"
                 latin:popupCharacters="@string/alternates_for_currency_euro" />
         </case>
+        <case
+            latin:languageCode="iw"
+        >
+            <key-style
+                latin:styleName="currencyKeyStyle"
+                latin:keyLabel="₪"
+                latin:popupCharacters="@string/alternates_for_currency_general" />
+        </case>
         <!-- United Kingdom -->
         <case
             latin:countryCode="GB"
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index cc949c9..aa1a005 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -47,7 +47,7 @@
             <key-style
                 latin:styleName="settingsPopupStyle"
                 latin:keyLabelOption="hasPopupHint"
-                latin:popupCharacters="\@icon/5|\@integer/key_settings"
+                latin:popupCharacters="\@icon/6|\@integer/key_settings"
                 latin:parentStyle="functionalKeyStyle" />
         </default>
     </switch>
@@ -60,7 +60,9 @@
         latin:parentStyle="functionalKeyStyle"
         latin:isSticky="true" />
     <switch>
-        <case latin:localeCode="ar|iw">
+        <case
+            latin:languageCode="ar|iw"
+        >
             <key-style
                 latin:styleName="deleteKeyStyle"
                 latin:code="@integer/key_delete"
@@ -225,4 +227,27 @@
                 latin:parentStyle="functionalKeyStyle" />
         </default>
     </switch>
+    <switch>
+        <case
+            latin:navigateAction="true"
+        >
+            <key-style
+                latin:styleName="punctuationKeyStyle"
+                latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
+                latin:keyLabelOption="hasPopupHint"
+                latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+                latin:maxPopupKeyboardColumn="@integer/popup_keyboard_column_for_web_punctuation"
+                latin:parentStyle="tabKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="punctuationKeyStyle"
+                latin:keyLabel="."
+                latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
+                latin:keyLabelOption="hasPopupHint"
+                latin:popupCharacters="@string/alternates_for_punctuation"
+                latin:maxPopupKeyboardColumn="@integer/popup_keyboard_column_for_punctuation"
+                latin:parentStyle="functionalKeyStyle" />
+        </default>
+    </switch>
 </merge>
diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml
index ff2ef3a..298f0f6 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/kbd_qwerty_row4.xml
@@ -41,27 +41,9 @@
                 <Key
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="35.83%p" />
-                <switch>
-                    <case
-                        latin:navigateAction="true"
-                    >
-                        <Key
-                            latin:keyStyle="tabKeyStyle"
-                            latin:keyLabelOption="hasPopupHint"
-                            latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
-                            latin:keyWidth="9.2%p"
-                            latin:maxPopupKeyboardColumn="8" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="."
-                            latin:keyLabelOption="hasPopupHint"
-                            latin:popupCharacters="@string/alternates_for_punctuation"
-                            latin:keyWidth="9.2%p"
-                            latin:maxPopupKeyboardColumn="7"
-                            latin:keyStyle="functionalKeyStyle" />
-                    </default>
-                </switch>
+                <Key
+                    latin:keyStyle="punctuationKeyStyle"
+                    latin:keyWidth="9.2%p" />
             </case>
             <!-- latin:hasSettingsKey="false" -->
             <default>
@@ -74,25 +56,8 @@
                 <Key
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="50%p" />
-                <switch>
-                    <case
-                        latin:navigateAction="true"
-                    >
-                        <Key
-                            latin:keyStyle="tabKeyStyle"
-                            latin:keyLabelOption="hasPopupHint"
-                            latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
-                            latin:maxPopupKeyboardColumn="8" />
-                    </case>
-                    <default>
-                        <Key
-                            latin:keyLabel="."
-                            latin:keyLabelOption="hasPopupHint"
-                            latin:popupCharacters="@string/alternates_for_punctuation"
-                            latin:maxPopupKeyboardColumn="7"
-                            latin:keyStyle="functionalKeyStyle" />
-                    </default>
-                </switch>
+                <Key
+                    latin:keyStyle="punctuationKeyStyle" />
             </default>
         </switch>
         <switch>
diff --git a/java/res/xml/kbd_rows_arabic.xml b/java/res/xml/kbd_rows_arabic.xml
index a548775..07e6274 100644
--- a/java/res/xml/kbd_rows_arabic.xml
+++ b/java/res/xml/kbd_rows_arabic.xml
@@ -18,9 +18,6 @@
 */
 -->
 
-<!-- This file for Arabic layout is an alpha version. It allows to enter   -->
-<!-- some right-to-left text, but it has gone through no study whatsoever, -->
-<!-- and needs to be run through UX.                                       -->
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
@@ -31,28 +28,49 @@
     >
         <Key
             latin:keyLabel="ض"
+            latin:keyHintLabel="1"
+            latin:popupCharacters="1,١"
             latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="ص" />
+            latin:keyLabel="ص"
+            latin:keyHintLabel="2"
+            latin:popupCharacters="2,٢" />
         <Key
-            latin:keyLabel="ق" />
+            latin:keyLabel="ق"
+            latin:keyHintLabel="3"
+            latin:popupCharacters="3,٣" />
+        <!-- \u06a4: ARABIC LETTER VEH -->
         <Key
             latin:keyLabel="ف"
-            latin:popupCharacters="ڤ" />
+            latin:keyHintLabel="4"
+            latin:popupCharacters="\u06a4,4,٤" />
         <Key
-            latin:keyLabel="غ" />
+            latin:keyLabel="غ"
+            latin:keyHintLabel="5"
+            latin:popupCharacters="5,٥" />
         <Key
-            latin:keyLabel="ع" />
+            latin:keyLabel="ع"
+            latin:keyHintLabel="6"
+            latin:popupCharacters="6,٦" />
+        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
+             \u0647\u0640: ARABIC LETTER HEH + ARABIC TATWEEL -->
         <Key
             latin:keyLabel="ه"
-            latin:popupCharacters="هـ" />
+            latin:keyHintLabel="7"
+            latin:popupCharacters="7,٧,\ufeeb|\u0647\u0640" />
         <Key
-            latin:keyLabel="خ" />
+            latin:keyLabel="خ"
+            latin:keyHintLabel="8"
+            latin:popupCharacters="8,٨" />
         <Key
-            latin:keyLabel="ح" />
+            latin:keyLabel="ح"
+            latin:keyHintLabel="9"
+            latin:popupCharacters="9,٩" />
+        <!-- \u0686: ARABIC LETTER TCHEH -->
         <Key
             latin:keyLabel="ج"
-            latin:popupCharacters="چ"
+            latin:keyHintLabel="0"
+            latin:popupCharacters="0,٠,\u0686"
             latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
@@ -64,20 +82,36 @@
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="س" />
+        <!-- \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE
+             \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
             latin:keyLabel="ي"
-            latin:popupCharacters="ى,ئ" />
+            latin:popupCharacters="\u0626,\u0649" />
         <Key
             latin:keyLabel="ب"
             latin:popupCharacters="پ" />
+        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+             \u0644: ARABIC LETTER LAM
+             \u0627: ARABIC LETTER ALEF
+             \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+             \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \ufef9: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \ufef5: ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ل"
-            latin:popupCharacters="لا" />
+            latin:popupCharacters="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
+        <!-- \u0621: ARABIC LETTER HAMZA
+             \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+             \u0625: ARABIC LETTER ALEF WITH HAMZA BELOW
+             \u0622: ARABIC LETTER ALEF WITH MADDA ABOVE -->
         <Key
             latin:keyLabel="ا"
-            latin:popupCharacters="أ,إ,آ,ء" />
+            latin:popupCharacters="\u0621,\u0623,\u0625,\u0622" />
         <Key
-            latin:keyLabel="ت" />
+            latin:keyLabel="ت"
+            latin:popupCharacters="ث" />
         <Key
             latin:keyLabel="ن" />
         <Key
@@ -89,10 +123,11 @@
             latin:keyEdgeFlags="right" />
     </Row>
     <Row
-        latin:keyWidth="9.7%p"
+        latin:keyWidth="10%p"
     >
         <Key
             latin:keyLabel="ظ"
+            latin:keyXPos="5.0%p"
             latin:keyEdgeFlags="left" />
         <Key
             latin:keyLabel="ط" />
@@ -106,17 +141,16 @@
         <Key
             latin:keyLabel="ر" />
         <Key
-            latin:keyLabel="و"
-            latin:popupCharacters="ؤ" />
-        <Key
             latin:keyLabel="ة" />
         <Key
-            latin:keyLabel="ث" />
+            latin:keyLabel="و"
+            latin:popupCharacters="ؤ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml/kbd_rows_hebrew.xml b/java/res/xml/kbd_rows_hebrew.xml
index c3c8f7d..af34885 100644
--- a/java/res/xml/kbd_rows_hebrew.xml
+++ b/java/res/xml/kbd_rows_hebrew.xml
@@ -18,9 +18,6 @@
 */
 -->
 
-<!-- This file for Hebrew layout is an alpha version. It allows to enter   -->
-<!-- some right-to-left text, but it has gone through no study whatsoever, -->
-<!-- and needs to be run through UX.                                       -->
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
@@ -63,15 +60,18 @@
         <Key
             latin:keyLabel="ד" />
         <Key
-            latin:keyLabel="ג" />
+            latin:keyLabel="ג"
+            latin:popupCharacters="ג׳" />
         <Key
             latin:keyLabel="כ" />
         <Key
             latin:keyLabel="ע" />
         <Key
-            latin:keyLabel="י" />
+            latin:keyLabel="י"
+            latin:popupCharacters="ײַ" />
         <Key
-            latin:keyLabel="ח" />
+            latin:keyLabel="ח"
+            latin:popupCharacters="ח׳" />
         <Key
             latin:keyLabel="ל" />
         <Key
@@ -86,6 +86,7 @@
     >
         <Key
             latin:keyLabel="ז"
+            latin:popupCharacters="ז׳"
             latin:keyXPos="5%p"
             latin:keyEdgeFlags="left" />
         <Key
@@ -99,13 +100,17 @@
         <Key
             latin:keyLabel="מ" />
         <Key
-            latin:keyLabel="צ" />
+            latin:keyLabel="צ"
+            latin:popupCharacters="צ׳" />
         <Key
-            latin:keyLabel="ת" />
+            latin:keyLabel="ת"
+            latin:popupCharacters="ת׳" />
         <Key
             latin:keyLabel="ץ"
+            latin:popupCharacters="ץ׳"
             latin:keyEdgeFlags="right" />
         <!-- Here is 5%p space -->
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_qwerty_row4" />
 </merge>
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 8e9124f..8f682d9 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -30,33 +30,36 @@
         latin:rowEdgeFlags="top"
     >
         <Key
-            latin:keyLabel="1"
-            latin:popupCharacters="¹,½,⅓,¼,⅛"
+            latin:keyLabel="@string/keylabel_for_symbols_1"
+            latin:popupCharacters="@string/alternates_for_symbols_1"
             latin:keyEdgeFlags="left" />
         <Key
-            latin:keyLabel="2"
-            latin:popupCharacters="²,⅔" />
+            latin:keyLabel="@string/keylabel_for_symbols_2"
+            latin:popupCharacters="@string/alternates_for_symbols_2" />
         <Key
-            latin:keyLabel="3"
-            latin:popupCharacters="³,¾,⅜" />
+            latin:keyLabel="@string/keylabel_for_symbols_3"
+            latin:popupCharacters="@string/alternates_for_symbols_3" />
         <Key
-            latin:keyLabel="4"
-            latin:popupCharacters="⁴" />
+            latin:keyLabel="@string/keylabel_for_symbols_4"
+            latin:popupCharacters="@string/alternates_for_symbols_4" />
         <Key
-            latin:keyLabel="5"
-            latin:popupCharacters="⅝" />
+            latin:keyLabel="@string/keylabel_for_symbols_5"
+            latin:popupCharacters="@string/alternates_for_symbols_5" />
         <Key
-            latin:keyLabel="6" />
+            latin:keyLabel="@string/keylabel_for_symbols_6"
+            latin:popupCharacters="@string/alternates_for_symbols_6" />
         <Key
-            latin:keyLabel="7"
-            latin:popupCharacters="⅞" />
+            latin:keyLabel="@string/keylabel_for_symbols_7"
+            latin:popupCharacters="@string/alternates_for_symbols_7" />
         <Key
-            latin:keyLabel="8" />
+            latin:keyLabel="@string/keylabel_for_symbols_8"
+            latin:popupCharacters="@string/alternates_for_symbols_8" />
         <Key
-            latin:keyLabel="9" />
+            latin:keyLabel="@string/keylabel_for_symbols_9"
+            latin:popupCharacters="@string/alternates_for_symbols_9" />
         <Key
-            latin:keyLabel="0"
-            latin:popupCharacters="ⁿ,∅"
+            latin:keyLabel="@string/keylabel_for_symbols_0"
+            latin:popupCharacters="@string/alternates_for_symbols_0"
             latin:keyWidth="fillRight"
             latin:keyEdgeFlags="right" />
     </Row>
@@ -112,17 +115,19 @@
         <Key
             latin:keyLabel=":" />
         <Key
-            latin:keyLabel=";" />
+            latin:keyLabel="@string/keylabel_for_symbols_semicolon"
+            latin:popupCharacters="@string/alternates_for_symbols_semicolon" />
         <Key
             latin:keyLabel="/" />
         <Key
-            latin:keyLabel="\?"
-            latin:popupCharacters="¿" />
+            latin:keyLabel="@string/keylabel_for_symbols_question"
+            latin:popupCharacters="@string/alternates_for_symbols_question" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight"
             latin:visualInsetsLeft="1%p"
             latin:keyEdgeFlags="right" />
     </Row>
-    <include latin:keyboardLayout="@xml/kbd_symbols_row4" />
+    <include
+        latin:keyboardLayout="@xml/kbd_symbols_row4" />
 </Keyboard>
diff --git a/java/res/xml/kbd_symbols_f1.xml b/java/res/xml/kbd_symbols_f1.xml
index da5b5fc..3c7346c 100644
--- a/java/res/xml/kbd_symbols_f1.xml
+++ b/java/res/xml/kbd_symbols_f1.xml
@@ -36,7 +36,8 @@
                 <!-- latin:hasVoiceKey="false" -->
                 <default>
                     <Key
-                        latin:keyLabel=","
+                        latin:keyLabel="@string/keylabel_for_symbols_comma"
+                        latin:popupCharacters="@string/alternates_for_symbols_comma"
                         latin:keyWidth="9.2%p"
                         latin:keyStyle="settingsPopupStyle" />
                 </default>
@@ -54,7 +55,8 @@
                 <!-- latin:hasVoiceKey="false" -->
                 <default>
                     <Key
-                        latin:keyLabel=","
+                        latin:keyLabel="@string/keylabel_for_symbols_comma"
+                        latin:popupCharacters="@string/alternates_for_symbols_comma"
                         latin:keyStyle="settingsPopupStyle" />
                 </default>
             </switch>
diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/kbd_symbols_row4.xml
index 68b79e8..34c06df 100644
--- a/java/res/xml/kbd_symbols_row4.xml
+++ b/java/res/xml/kbd_symbols_row4.xml
@@ -42,12 +42,8 @@
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="35.83%p" />
                 <Key
-                    latin:keyLabel="."
-                    latin:keyLabelOption="hasPopupHint"
-                    latin:popupCharacters="@string/alternates_for_punctuation"
-                    latin:keyWidth="9.2%p"
-                    latin:maxPopupKeyboardColumn="7"
-                    latin:keyStyle="functionalKeyStyle" />
+                    latin:keyStyle="punctuationKeyStyle"
+                    latin:keyWidth="9.2%p" />
             </case>
             <!-- latin:hasSettingsKey="false" -->
             <default>
@@ -61,11 +57,7 @@
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="50%p" />
                 <Key
-                    latin:keyLabel="."
-                    latin:keyLabelOption="hasPopupHint"
-                    latin:popupCharacters="@string/alternates_for_punctuation"
-                    latin:maxPopupKeyboardColumn="7"
-                    latin:keyStyle="functionalKeyStyle" />
+                    latin:keyStyle="punctuationKeyStyle" />
             </default>
         </switch>
         <switch>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 9558853..45bf68c 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -257,10 +257,13 @@
 
             final CharSequence[] popupCharacters = style.getTextArray(keyAttr,
                     R.styleable.Keyboard_Key_popupCharacters);
-            if (res.getBoolean(R.bool.config_digit_popup_characters_enabled)) {
-                mPopupCharacters = popupCharacters;
-            } else {
+            // In Arabic symbol layouts, we'd like to keep digits in popup characters regardless of
+            // config_digit_popup_characters_enabled.
+            if (mKeyboard.mId.isAlphabetKeyboard() && !res.getBoolean(
+                    R.bool.config_digit_popup_characters_enabled)) {
                 mPopupCharacters = filterOutDigitPopupCharacters(popupCharacters);
+            } else {
+                mPopupCharacters = popupCharacters;
             }
             mMaxPopupColumn = style.getInt(keyboardAttr,
                     R.styleable.Keyboard_Key_maxPopupKeyboardColumn,
diff --git a/native/src/basechars.h b/native/src/basechars.h
index 5a44066..3843e11 100644
--- a/native/src/basechars.h
+++ b/native/src/basechars.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_BASECHARS_H
+#define LATINIME_BASECHARS_H
+
 /**
  * Table mapping most combined Latin, Greek, and Cyrillic characters
  * to their base characters.  If c is in range, BASE_CHARS[c] == c
@@ -170,3 +189,4 @@
 
 // generated with:
 // cat UnicodeData.txt | perl -e 'while (<>) { @foo = split(/;/); $foo[5] =~ s/<.*> //; $base[hex($foo[0])] = hex($foo[5]);} for ($i = 0; $i < 0x500; $i += 8) { for ($j = $i; $j < $i + 8; $j++) { printf("0x%04x, ", $base[$j] ? $base[$j] : $j)}; print "\n"; }'
+#endif // LATINIME_BASECHARS_H
diff --git a/native/src/dictionary.h b/native/src/dictionary.h
index 3dc577a..73e03d8 100644
--- a/native/src/dictionary.h
+++ b/native/src/dictionary.h
@@ -17,7 +17,9 @@
 #ifndef LATINIME_DICTIONARY_H
 #define LATINIME_DICTIONARY_H
 
+#include "basechars.h"
 #include "bigram_dictionary.h"
+#include "char_utils.h"
 #include "defines.h"
 #include "proximity_info.h"
 #include "unigram_dictionary.h"
@@ -61,7 +63,7 @@
     static int setDictionaryValues(const unsigned char *dict, const bool isLatestDictVersion,
             const int pos, unsigned short *c, int *childrenPosition,
             bool *terminal, int *freq);
-
+    static inline unsigned short toBaseLowerCase(unsigned short c);
     // TODO: delete this
     int getBigramPosition(unsigned short *word, int length);
 
@@ -156,6 +158,19 @@
     return position;
 }
 
+
+inline unsigned short Dictionary::toBaseLowerCase(unsigned short c) {
+    if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
+        c = BASE_CHARS[c];
+    }
+    if (c >='A' && c <= 'Z') {
+        c |= 32;
+    } else if (c > 127) {
+        c = latin_tolower(c);
+    }
+    return c;
+}
+
 } // namespace latinime
 
 #endif // LATINIME_DICTIONARY_H
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index 209c31e..c45393f 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -19,6 +19,7 @@
 
 #define LOG_TAG "LatinIME: proximity_info.cpp"
 
+#include "dictionary.h"
 #include "proximity_info.h"
 
 namespace latinime {
@@ -63,4 +64,101 @@
     return false;
 }
 
+// TODO: Calculate nearby codes here.
+void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength) {
+    mInputCodes = inputCodes;
+    mInputLength = inputLength;
+}
+
+inline const int* ProximityInfo::getProximityCharsAt(const int index) const {
+    return mInputCodes + (index * MAX_PROXIMITY_CHARS_SIZE);
+}
+
+unsigned short ProximityInfo::getPrimaryCharAt(const int index) const {
+    return getProximityCharsAt(index)[0];
+}
+
+bool ProximityInfo::existsCharInProximityAt(const int index, const int c) const {
+    const int *chars = getProximityCharsAt(index);
+    int i = 0;
+    while (chars[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE) {
+        if (chars[i++] == c) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool ProximityInfo::existsAdjacentProximityChars(const int index) const {
+    if (index < 0 || index >= mInputLength) return false;
+    const int currentChar = getPrimaryCharAt(index);
+    const int leftIndex = index - 1;
+    if (leftIndex >= 0 && existsCharInProximityAt(leftIndex, currentChar)) {
+        return true;
+    }
+    const int rightIndex = index + 1;
+    if (rightIndex < mInputLength && existsCharInProximityAt(rightIndex, currentChar)) {
+        return true;
+    }
+    return false;
+}
+
+// In the following function, c is the current character of the dictionary word
+// currently examined.
+// currentChars is an array containing the keys close to the character the
+// user actually typed at the same position. We want to see if c is in it: if so,
+// then the word contains at that position a character close to what the user
+// typed.
+// What the user typed is actually the first character of the array.
+// Notice : accented characters do not have a proximity list, so they are alone
+// in their list. The non-accented version of the character should be considered
+// "close", but not the other keys close to the non-accented version.
+ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
+        const int index, const unsigned short c, const int skipPos,
+        const int excessivePos, const int transposedPos) const {
+    const int *currentChars = getProximityCharsAt(index);
+    const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
+
+    // The first char in the array is what user typed. If it matches right away,
+    // that means the user typed that same char for this pos.
+    if (currentChars[0] == baseLowerC || currentChars[0] == c)
+        return SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR;
+
+    // If one of those is true, we should not check for close characters at all.
+    if (skipPos >= 0 || excessivePos >= 0 || transposedPos >= 0)
+        return UNRELATED_CHAR;
+
+    // If the non-accented, lowercased version of that first character matches c,
+    // then we have a non-accented version of the accented character the user
+    // typed. Treat it as a close char.
+    if (Dictionary::toBaseLowerCase(currentChars[0]) == baseLowerC)
+        return NEAR_PROXIMITY_CHAR;
+
+    // Not an exact nor an accent-alike match: search the list of close keys
+    int j = 1;
+    while (currentChars[j] > 0 && j < MAX_PROXIMITY_CHARS_SIZE) {
+        const bool matched = (currentChars[j] == baseLowerC || currentChars[j] == c);
+        if (matched) return NEAR_PROXIMITY_CHAR;
+        ++j;
+    }
+
+    // Was not included, signal this as an unrelated character.
+    return UNRELATED_CHAR;
+}
+
+bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const {
+    if (length != mInputLength) {
+        return false;
+    }
+    const int *inputCodes = mInputCodes;
+    while (length--) {
+        if ((unsigned int) *inputCodes != (unsigned int) *word) {
+            return false;
+        }
+        inputCodes += MAX_PROXIMITY_CHARS_SIZE;
+        word++;
+    }
+    return true;
+}
+
 } // namespace latinime
diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h
index 327cd09..435a601 100644
--- a/native/src/proximity_info.h
+++ b/native/src/proximity_info.h
@@ -25,11 +25,26 @@
 
 class ProximityInfo {
 public:
+    typedef enum {                             // Used as a return value for character comparison
+        SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR,  // Same char, possibly with different case or accent
+        NEAR_PROXIMITY_CHAR,                   // It is a char located nearby on the keyboard
+        UNRELATED_CHAR                         // It is an unrelated char
+    } ProximityType;
+
     ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
             const int keybaordHeight, const int gridWidth, const int gridHeight,
             const uint32_t *proximityCharsArray);
     ~ProximityInfo();
     bool hasSpaceProximity(const int x, const int y) const;
+    void setInputParams(const int* inputCodes, const int inputLength);
+    const int* getProximityCharsAt(const int index) const;
+    unsigned short getPrimaryCharAt(const int index) const;
+    bool existsCharInProximityAt(const int index, const int c) const;
+    bool existsAdjacentProximityChars(const int index) const;
+    ProximityType getMatchedProximityId(
+            const int index, const unsigned short c, const int skipPos,
+            const int excessivePos, const int transposedPos) const;
+    bool sameAsTyped(const unsigned short *word, int length) const;
 private:
     int getStartIndexFromCoordinates(const int x, const int y) const;
     const int MAX_PROXIMITY_CHARS_SIZE;
@@ -39,7 +54,9 @@
     const int GRID_HEIGHT;
     const int CELL_WIDTH;
     const int CELL_HEIGHT;
+    const int *mInputCodes;
     uint32_t *mProximityCharsArray;
+    int mInputLength;
 };
 
 } // namespace latinime
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index 5e72c76..afa8bc5 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -20,7 +20,6 @@
 
 #define LOG_TAG "LatinIME: unigram_dictionary.cpp"
 
-#include "basechars.h"
 #include "char_utils.h"
 #include "dictionary.h"
 #include "unigram_dictionary.h"
@@ -54,7 +53,7 @@
       // TODO : remove this variable.
     ROOT_POS(0),
 #endif // NEW_DICTIONARY_FORMAT
-    BYTES_IN_ONE_CHAR(MAX_PROXIMITY_CHARS * sizeof(*mInputCodes)),
+    BYTES_IN_ONE_CHAR(MAX_PROXIMITY_CHARS * sizeof(int)),
     MAX_UMLAUT_SEARCH_DEPTH(DEFAULT_MAX_UMLAUT_SEARCH_DEPTH) {
     if (DEBUG_DICT) {
         LOGI("UnigramDictionary - constructor");
@@ -93,7 +92,7 @@
 // codesDest is the current point in the work buffer.
 // codesSrc is the current point in the user-input, original, content-unmodified buffer.
 // codesRemain is the remaining size in codesSrc.
-void UnigramDictionary::getWordWithDigraphSuggestionsRec(const ProximityInfo *proximityInfo,
+void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo,
         const int *xcoordinates, const int* ycoordinates, const int *codesBuffer,
         const int codesBufferSize, const int flags, const int* codesSrc, const int codesRemain,
         const int currentDepth, int* codesDest, unsigned short* outWords, int* frequencies) {
@@ -143,7 +142,7 @@
             (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS + codesRemain, outWords, frequencies);
 }
 
-int UnigramDictionary::getSuggestions(const ProximityInfo *proximityInfo, const int *xcoordinates,
+int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
         const int *ycoordinates, const int *codes, const int codesSize, const int flags,
         unsigned short *outWords, int *frequencies) {
 
@@ -187,13 +186,14 @@
     return suggestedWordsCount;
 }
 
-void UnigramDictionary::getWordSuggestions(const ProximityInfo *proximityInfo,
+void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
         const int *xcoordinates, const int *ycoordinates, const int *codes, const int codesSize,
         unsigned short *outWords, int *frequencies) {
 
     PROF_OPEN;
     PROF_START(0);
-    initSuggestions(codes, codesSize, outWords, frequencies);
+    initSuggestions(
+            proximityInfo, xcoordinates, ycoordinates, codes, codesSize, outWords, frequencies);
     if (DEBUG_DICT) assert(codesSize == mInputLength);
 
     const int MAX_DEPTH = min(mInputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH);
@@ -275,16 +275,18 @@
     PROF_END(6);
 }
 
-void UnigramDictionary::initSuggestions(const int *codes, const int codesSize,
+void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
+        const int *ycoordinates, const int *codes, const int codesSize,
         unsigned short *outWords, int *frequencies) {
     if (DEBUG_DICT) {
         LOGI("initSuggest");
     }
     mFrequencies = frequencies;
     mOutputChars = outWords;
-    mInputCodes = codes;
     mInputLength = codesSize;
     mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2;
+    proximityInfo->setInputParams(codes, codesSize);
+    mProximityInfo = proximityInfo;
 }
 
 static inline void registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize) {
@@ -348,33 +350,6 @@
     return false;
 }
 
-static inline unsigned short toBaseLowerCase(unsigned short c) {
-    if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
-        c = BASE_CHARS[c];
-    }
-    if (c >='A' && c <= 'Z') {
-        c |= 32;
-    } else if (c > 127) {
-        c = latin_tolower(c);
-    }
-    return c;
-}
-
-bool UnigramDictionary::sameAsTyped(const unsigned short *word, int length) const {
-    if (length != mInputLength) {
-        return false;
-    }
-    const int *inputCodes = mInputCodes;
-    while (length--) {
-        if ((unsigned int) *inputCodes != (unsigned int) *word) {
-            return false;
-        }
-        inputCodes += MAX_PROXIMITY_CHARS;
-        word++;
-    }
-    return true;
-}
-
 static const char QUOTE = '\'';
 static const char SPACE = ' ';
 
@@ -568,7 +543,9 @@
             WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE, &finalFreq);
     if (excessivePos >= 0) {
         multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE, &finalFreq);
-        if (!existsAdjacentProximityChars(inputIndex, mInputLength)) {
+        if (!mProximityInfo->existsAdjacentProximityChars(inputIndex)) {
+            // If an excessive character is not adjacent to the left char or the right char,
+            // we will demote this word.
             multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE, &finalFreq);
         }
     }
@@ -602,75 +579,11 @@
 
 inline bool UnigramDictionary::needsToSkipCurrentNode(const unsigned short c,
         const int inputIndex, const int skipPos, const int depth) {
-    const unsigned short userTypedChar = getInputCharsAt(inputIndex)[0];
+    const unsigned short userTypedChar = mProximityInfo->getPrimaryCharAt(inputIndex);
     // Skip the ' or other letter and continue deeper
     return (c == QUOTE && userTypedChar != QUOTE) || skipPos == depth;
 }
 
-inline bool UnigramDictionary::existsAdjacentProximityChars(const int inputIndex,
-        const int inputLength) const {
-    if (inputIndex < 0 || inputIndex >= inputLength) return false;
-    const int currentChar = *getInputCharsAt(inputIndex);
-    const int leftIndex = inputIndex - 1;
-    if (leftIndex >= 0) {
-        const int *leftChars = getInputCharsAt(leftIndex);
-        int i = 0;
-        while (leftChars[i] > 0 && i < MAX_PROXIMITY_CHARS) {
-            if (leftChars[i++] == currentChar) return true;
-        }
-    }
-    const int rightIndex = inputIndex + 1;
-    if (rightIndex < inputLength) {
-        const int *rightChars = getInputCharsAt(rightIndex);
-        int i = 0;
-        while (rightChars[i] > 0 && i < MAX_PROXIMITY_CHARS) {
-            if (rightChars[i++] == currentChar) return true;
-        }
-    }
-    return false;
-}
-
-// In the following function, c is the current character of the dictionary word
-// currently examined.
-// currentChars is an array containing the keys close to the character the
-// user actually typed at the same position. We want to see if c is in it: if so,
-// then the word contains at that position a character close to what the user
-// typed.
-// What the user typed is actually the first character of the array.
-// Notice : accented characters do not have a proximity list, so they are alone
-// in their list. The non-accented version of the character should be considered
-// "close", but not the other keys close to the non-accented version.
-inline UnigramDictionary::ProximityType UnigramDictionary::getMatchedProximityId(
-        const int *currentChars, const unsigned short c, const int skipPos,
-        const int excessivePos, const int transposedPos) {
-    const unsigned short baseLowerC = toBaseLowerCase(c);
-
-    // The first char in the array is what user typed. If it matches right away,
-    // that means the user typed that same char for this pos.
-    if (currentChars[0] == baseLowerC || currentChars[0] == c)
-        return SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR;
-
-    // If one of those is true, we should not check for close characters at all.
-    if (skipPos >= 0 || excessivePos >= 0 || transposedPos >= 0)
-        return UNRELATED_CHAR;
-
-    // If the non-accented, lowercased version of that first character matches c,
-    // then we have a non-accented version of the accented character the user
-    // typed. Treat it as a close char.
-    if (toBaseLowerCase(currentChars[0]) == baseLowerC)
-        return NEAR_PROXIMITY_CHAR;
-
-    // Not an exact nor an accent-alike match: search the list of close keys
-    int j = 1;
-    while (currentChars[j] > 0 && j < MAX_PROXIMITY_CHARS) {
-        const bool matched = (currentChars[j] == baseLowerC || currentChars[j] == c);
-        if (matched) return NEAR_PROXIMITY_CHAR;
-        ++j;
-    }
-
-    // Was not included, signal this as an unrelated character.
-    return UNRELATED_CHAR;
-}
 
 inline void UnigramDictionary::onTerminal(unsigned short int* word, const int depth,
         const uint8_t* const root, const uint8_t flags, const int pos,
@@ -678,7 +591,7 @@
         const int excessivePos, const int transposedPos, const int freq, const bool sameLength,
         int* nextLetters, const int nextLettersSize) {
 
-    const bool isSameAsTyped = sameLength ? sameAsTyped(word, depth + 1) : false;
+    const bool isSameAsTyped = sameLength ? mProximityInfo->sameAsTyped(word, depth + 1) : false;
     if (isSameAsTyped) return;
 
     if (depth >= MIN_SUGGEST_DEPTH) {
@@ -836,15 +749,14 @@
         const int startInputIndex, const int depth, unsigned short *word, int *newChildPosition,
         int *newCount, bool *newTerminal, int *newFreq, int *siblingPos) {
     const int inputIndex = startInputIndex + depth;
-    const int *currentChars = getInputCharsAt(inputIndex);
     unsigned short c;
     *siblingPos = Dictionary::setDictionaryValues(DICT_ROOT, IS_LATEST_DICT_VERSION, firstChildPos,
             &c, newChildPosition, newTerminal, newFreq);
-    const unsigned int inputC = currentChars[0];
+    const unsigned int inputC = mProximityInfo->getPrimaryCharAt(inputIndex);
     if (DEBUG_DICT) {
         assert(inputC <= U_SHORT_MAX);
     }
-    const unsigned short baseLowerC = toBaseLowerCase(c);
+    const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
     const bool matched = (inputC == baseLowerC || inputC == c);
     const bool hasChild = *newChildPosition != 0;
     if (matched) {
@@ -962,20 +874,20 @@
         *newDiffs = diffs;
         *newInputIndex = inputIndex;
     } else {
-        const int *currentChars = getInputCharsAt(inputIndex);
+        int inputIndexForProximity = inputIndex;
 
         if (transposedPos >= 0) {
-            if (inputIndex == transposedPos) currentChars += MAX_PROXIMITY_CHARS;
-            if (inputIndex == (transposedPos + 1)) currentChars -= MAX_PROXIMITY_CHARS;
+            if (inputIndex == transposedPos) ++inputIndexForProximity;
+            if (inputIndex == (transposedPos + 1)) --inputIndexForProximity;
         }
 
-        int matchedProximityCharId = getMatchedProximityId(currentChars, c, skipPos, excessivePos,
-                transposedPos);
-        if (UNRELATED_CHAR == matchedProximityCharId) return false;
+        ProximityInfo::ProximityType matchedProximityCharId = mProximityInfo->getMatchedProximityId(
+                inputIndexForProximity, c, skipPos, excessivePos, transposedPos);
+        if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) return false;
         mWord[depth] = c;
         // If inputIndex is greater than mInputLength, that means there is no
         // proximity chars. So, we don't need to check proximity.
-        if (SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
+        if (ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
             multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &matchWeight);
         }
         bool isSameAsUserTypedLength = mInputLength == inputIndex + 1
@@ -988,7 +900,8 @@
         // Start traversing all nodes after the index exceeds the user typed length
         *newTraverseAllNodes = isSameAsUserTypedLength;
         *newMatchRate = matchWeight;
-        *newDiffs = diffs + ((NEAR_PROXIMITY_CHAR == matchedProximityCharId) ? 1 : 0);
+        *newDiffs = diffs
+                + ((ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) ? 1 : 0);
         *newInputIndex = inputIndex + 1;
     }
     // Optimization: Prune out words that are too long compared to how much was typed.
@@ -1017,7 +930,7 @@
     uint16_t inWord[inputLength];
 
     for (int i = 0; i < inputLength; ++i) {
-        inWord[i] = *getInputCharsAt(startInputIndex + i);
+        inWord[i] = (uint16_t)mProximityInfo->getPrimaryCharAt(startInputIndex + i);
     }
     return getMostFrequentWordLikeInner(inWord, inputLength, word);
 }
@@ -1041,8 +954,8 @@
     const bool hasMultipleChars = (0 != (UnigramDictionary::FLAG_HAS_MULTIPLE_CHARS & flags));
     int pos = startPos;
     int32_t character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
-    int32_t baseChar = toBaseLowerCase(character);
-    const uint16_t wChar = toBaseLowerCase(inWord[startInputIndex]);
+    int32_t baseChar = Dictionary::toBaseLowerCase(character);
+    const uint16_t wChar = Dictionary::toBaseLowerCase(inWord[startInputIndex]);
 
     if (baseChar != wChar) {
         *outPos = hasMultipleChars ? BinaryFormat::skipOtherCharacters(root, pos) : pos;
@@ -1054,8 +967,8 @@
     if (hasMultipleChars) {
         character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
         while (NOT_A_CHARACTER != character) {
-            baseChar = toBaseLowerCase(character);
-            if (toBaseLowerCase(inWord[++inputIndex]) != baseChar) {
+            baseChar = Dictionary::toBaseLowerCase(character);
+            if (Dictionary::toBaseLowerCase(inWord[++inputIndex]) != baseChar) {
                 *outPos = BinaryFormat::skipOtherCharacters(root, pos);
                 *outInputIndex = startInputIndex;
                 return false;
@@ -1300,7 +1213,7 @@
         const bool hasChildren = (!isLastChar) || BinaryFormat::hasChildrenInFlags(flags);
 
         // This has to be done for each virtual char (this forwards the "inputIndex" which
-        // is the index in the user-inputted chars, as read by getInputCharsAt.
+        // is the index in the user-inputted chars, as read by proximity chars.
         if (excessivePos == depth && inputIndex < mInputLength - 1) ++inputIndex;
         if (traverseAllNodes || needsToSkipCurrentNode(c, inputIndex, skipPos, depth)) {
             mWord[depth] = c;
@@ -1324,16 +1237,16 @@
                 return false;
             }
         } else {
-            const int *currentChars = getInputCharsAt(inputIndex);
+            int inputIndexForProximity = inputIndex;
 
             if (transposedPos >= 0) {
-                if (inputIndex == transposedPos) currentChars += MAX_PROXIMITY_CHARS;
-                if (inputIndex == (transposedPos + 1)) currentChars -= MAX_PROXIMITY_CHARS;
+                if (inputIndex == transposedPos) ++inputIndexForProximity;
+                if (inputIndex == (transposedPos + 1)) --inputIndexForProximity;
             }
 
-            const int matchedProximityCharId = getMatchedProximityId(currentChars, c, skipPos,
-                    excessivePos, transposedPos);
-            if (UNRELATED_CHAR == matchedProximityCharId) {
+            int matchedProximityCharId = mProximityInfo->getMatchedProximityId(
+                    inputIndexForProximity, c, skipPos, excessivePos, transposedPos);
+            if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) {
                 // We found that this is an unrelated character, so we should give up traversing
                 // this node and its children entirely.
                 // However we may not be on the last virtual node yet so we skip the remaining
@@ -1352,7 +1265,7 @@
             mWord[depth] = c;
             // If inputIndex is greater than mInputLength, that means there is no
             // proximity chars. So, we don't need to check proximity.
-            if (SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
+            if (ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
                 multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &matchWeight);
             }
             const bool isSameAsUserTypedLength = mInputLength == inputIndex + 1
@@ -1376,7 +1289,8 @@
             }
             // Start traversing all nodes after the index exceeds the user typed length
             traverseAllNodes = isSameAsUserTypedLength;
-            diffs = diffs + ((NEAR_PROXIMITY_CHAR == matchedProximityCharId) ? 1 : 0);
+            diffs = diffs
+                    + ((ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) ? 1 : 0);
             // Finally, we are ready to go to the next character, the next "virtual node".
             // We should advance the input index.
             // We do this in this branch of the 'if traverseAllNodes' because we are still matching
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index dcc8f2a..f6045c6 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -29,12 +29,6 @@
 
 class UnigramDictionary {
 
-    typedef enum {                             // Used as a return value for character comparison
-        SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR,  // Same char, possibly with different case or accent
-        NEAR_PROXIMITY_CHAR,                   // It is a char located nearby on the keyboard
-        UNRELATED_CHAR                         // It is an unrelated char
-    } ProximityType;
-
 public:
 #ifdef NEW_DICTIONARY_FORMAT
 
@@ -82,26 +76,26 @@
             int maxAlternatives);
 #endif // NEW_DICTIONARY_FORMAT
     int getBigramPosition(int pos, unsigned short *word, int offset, int length) const;
-    int getSuggestions(const ProximityInfo *proximityInfo, const int *xcoordinates,
+    int getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
             const int *ycoordinates, const int *codes, const int codesSize, const int flags,
             unsigned short *outWords, int *frequencies);
     ~UnigramDictionary();
 
 private:
-    void getWordSuggestions(const ProximityInfo *proximityInfo, const int *xcoordinates,
+    void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
             const int *ycoordinates, const int *codes, const int codesSize,
             unsigned short *outWords, int *frequencies);
     bool isDigraph(const int* codes, const int i, const int codesSize) const;
-    void getWordWithDigraphSuggestionsRec(const ProximityInfo *proximityInfo,
+    void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo,
         const int *xcoordinates, const int* ycoordinates, const int *codesBuffer,
         const int codesBufferSize, const int flags, const int* codesSrc, const int codesRemain,
         const int currentDepth, int* codesDest, unsigned short* outWords, int* frequencies);
-    void initSuggestions(const int *codes, const int codesSize, unsigned short *outWords,
-            int *frequencies);
+    void initSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
+            const int *ycoordinates, const int *codes, const int codesSize,
+            unsigned short *outWords, int *frequencies);
     void getSuggestionCandidates(const int skipPos, const int excessivePos,
             const int transposedPos, int *nextLetters, const int nextLettersSize,
             const int maxDepth);
-    bool sameAsTyped(const unsigned short *word, int length) const;
     bool addWord(unsigned short *word, int length, int frequency);
     bool getSplitTwoWordsSuggestion(const int inputLength,
             const int firstWordStartPos, const int firstWordLength,
@@ -118,8 +112,6 @@
             int *nextLetters, const int nextLettersSize);
     bool needsToSkipCurrentNode(const unsigned short c,
             const int inputIndex, const int skipPos, const int depth);
-    ProximityType getMatchedProximityId(const int *currentChars, const unsigned short c,
-            const int skipPos, const int excessivePos, const int transposedPos);
     // Process a node by considering proximity, missing and excessive character
     bool processCurrentNode(const int initialPos, const int initialDepth,
             const int maxDepth, const bool initialTraverseAllNodes, const int snr, int inputIndex,
@@ -127,10 +119,6 @@
             const int transposedPos, int *nextLetters, const int nextLettersSize, int *newCount,
             int *newChildPosition, bool *newTraverseAllNodes, int *newSnr, int*newInputIndex,
             int *newDiffs, int *nextSiblingPosition, int *nextOutputIndex);
-    bool existsAdjacentProximityChars(const int inputIndex, const int inputLength) const;
-    inline const int* getInputCharsAt(const int index) const {
-        return mInputCodes + (index * MAX_PROXIMITY_CHARS);
-    }
     int getMostFrequentWordLike(const int startInputIndex, const int inputLength,
             unsigned short *word);
 #ifndef NEW_DICTIONARY_FORMAT
@@ -174,7 +162,7 @@
 
     int *mFrequencies;
     unsigned short *mOutputChars;
-    const int *mInputCodes;
+    const ProximityInfo *mProximityInfo;
     int mInputLength;
     // MAX_WORD_LENGTH_INTERNAL must be bigger than MAX_WORD_LENGTH
     unsigned short mWord[MAX_WORD_LENGTH_INTERNAL];
@@ -189,7 +177,6 @@
     int mStackOutputIndex[MAX_WORD_LENGTH_INTERNAL];
     int mNextLettersFrequency[NEXT_LETTERS_SIZE];
 };
-
 } // namespace latinime
 
 #endif // LATINIME_UNIGRAM_DICTIONARY_H