merge in ics-release history after reset to master
diff --git a/java/res/values-ar/donottranslate-more-keys.xml b/java/res/values-ar/donottranslate-more-keys.xml
index 39d38a5..36f670e 100644
--- a/java/res/values-ar/donottranslate-more-keys.xml
+++ b/java/res/values-ar/donottranslate-more-keys.xml
@@ -20,18 +20,24 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- \u060c: ARABIC COMMA
          \u061b: ARABIC SEMICOLON
-         \u061f: ARABIC QUESTION MARK
-         \u0651: ARABIC SHADDA
+         \u061f: ARABIC QUESTION MARK -->
+    <!-- \u0650: ARABIC KASRA
+         \u064e: ARABIC FATHA
+         \u064b: ARABIC FATHATAN
+         \u0640: ARABIC TATWEEL
+         \u064d: ARABIC KASRATAN
+         \u0670: ARABIC LETTER SUPERSCRIPT ALEF
+         \u0656: ARABIC SUBSCRIPT ALEF
+         \u0654: ARABIC HAMZA ABOVE
+         \u0655: ARABIC HAMZA BELOW -->
+    <!-- \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 -->
+         \u0653: ARABIC MADDAH ABOVE
+         \u064f: ARABIC DAMMA -->
     <!-- In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. -->
-    <string name="more_keys_for_punctuation">"\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0651,\u0640\u0640\u0640|\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
+    <!-- TODO: Will introduce "grouping marks" to the more characters specification. -->
+    <string name="more_keys_for_punctuation">"\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0640\u0640\u0640|\u0640,\u064e,\u0650,\u064b,\u064d,\u0670,\u0656,\u0655,\u0654,\u0653,\u0652,\u0651,\u064c,\u064f"</string>
     <integer name="mini_keyboard_column_for_punctuation">9</integer>
     <string name="keyhintlabel_for_punctuation">\u064b</string>
     <string name="keylabel_for_symbols_1">"١"</string>
@@ -44,16 +50,18 @@
     <string name="keylabel_for_symbols_8">"٨"</string>
     <string name="keylabel_for_symbols_9">"٩"</string>
     <string name="keylabel_for_symbols_0">"٠"</string>
-    <string name="more_keys_for_symbols_1">1,¹,½,⅓,¼,⅛</string>
-    <string name="more_keys_for_symbols_2">2,²,⅔</string>
-    <string name="more_keys_for_symbols_3">3,³,¾,⅜</string>
-    <string name="more_keys_for_symbols_4">4,⁴</string>
-    <string name="more_keys_for_symbols_5">5,⅝</string>
+    <string name="more_keys_for_symbols_1">1</string>
+    <string name="more_keys_for_symbols_2">2</string>
+    <string name="more_keys_for_symbols_3">3</string>
+    <string name="more_keys_for_symbols_4">4</string>
+    <string name="more_keys_for_symbols_5">5</string>
     <string name="more_keys_for_symbols_6">6</string>
-    <string name="more_keys_for_symbols_7">7,⅞</string>
+    <string name="more_keys_for_symbols_7">7</string>
     <string name="more_keys_for_symbols_8">8</string>
     <string name="more_keys_for_symbols_9">9</string>
-    <string name="more_keys_for_symbols_0">0,ⁿ,∅</string>
+    <!-- \u066b: ARABIC DECIMAL SEPARATOR
+         \u066c: ARABIC THOUSANDS SEPARATOR -->
+    <string name="more_keys_for_symbols_0">0,\u066b,\u066c</string>
     <string name="keylabel_for_comma">\u060c</string>
     <string name="keylabel_for_f1">\u060c</string>
     <string name="keylabel_for_symbols_question">\u061f</string>
@@ -66,16 +74,33 @@
     <string name="more_keys_for_f1_settings">\\,,\@icon/3|\@integer/key_settings</string>
     <!-- @icon/7 is iconTabKey -->
     <string name="more_keys_for_f1_navigate">\\,,\@icon/7|\@integer/key_tab</string>
-    <string name="more_keys_for_symbols_question">\?,¿</string>
+    <string name="more_keys_for_symbols_question">\?</string>
     <string name="more_keys_for_symbols_semicolon">;</string>
     <string name="more_keys_for_symbols_percent">%,‰</string>
-    <string name="keylabel_for_apostrophe">"،"</string>
+    <!-- \u060c: ARABIC COMMA
+         \u061b: ARABIC SEMICOLON
+         \u061f: ARABIC QUESTION MARK -->
+    <string name="keylabel_for_apostrophe">"\u060c"</string>
     <string name="keylabel_for_dash">"."</string>
-    <string name="keyhintlabel_for_apostrophe">"؟"</string>
+    <string name="keyhintlabel_for_apostrophe">"\u061f"</string>
     <string name="keyhintlabel_for_dash">"\u064b"</string>
     <string name="more_keys_for_apostrophe">"\u061f,\u061b,!,:,-,/,\',\""</string>
+    <!-- \u0651: ARABIC SHADDA
+         \u0652: ARABIC SUKUN
+         \u064c: ARABIC DAMMATAN
+         \u0653: ARABIC MADDAH ABOVE
+         \u064f: ARABIC DAMMA -->
+    <!-- \u0650: ARABIC KASRA
+         \u064e: ARABIC FATHA
+         \u064b: ARABIC FATHATAN
+         \u0640: ARABIC TATWEEL
+         \u064d: ARABIC KASRATAN -->
+    <!-- \u0670: ARABIC LETTER SUPERSCRIPT ALEF
+         \u0656: ARABIC SUBSCRIPT ALEF
+         \u0654: ARABIC HAMZA ABOVE
+         \u0655: ARABIC HAMZA BELOW -->
     <!-- In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. -->
-    <string name="more_keys_for_dash">"\u0651,\u0652,\u064c,\u0640\u0640\u0640|\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
+    <string name="more_keys_for_dash">"\u0651,\u0652,\u064c,\u0653,\u064f,\u0650,\u064e,\u064b,\u0640\u0640\u0640|\u0640,\u064d,\u0654,\u0656,\u0655,\u0670"</string>
     <string name="more_keys_for_bullet">♪</string>
     <string name="more_keys_for_star">★</string>
 </resources>
diff --git a/java/res/values-hdpi/keyboard_key_feedback_background_holo.xml b/java/res/values-hdpi/keyboard_key_feedback_background_holo.xml
new file mode 100644
index 0000000..8ab3226
--- /dev/null
+++ b/java/res/values-hdpi/keyboard_key_feedback_background_holo.xml
@@ -0,0 +1,24 @@
+<?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>
+    <dimen name="keyboard_key_feedback_background_holo_width">46.67dp</dimen>
+    <dimen name="keyboard_key_feedback_background_holo_height">58.67dp</dimen>
+</resources>
diff --git a/java/res/values-mdpi/keyboard_key_feedback_background_holo.xml b/java/res/values-mdpi/keyboard_key_feedback_background_holo.xml
new file mode 100644
index 0000000..10fef3d
--- /dev/null
+++ b/java/res/values-mdpi/keyboard_key_feedback_background_holo.xml
@@ -0,0 +1,24 @@
+<?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>
+    <dimen name="keyboard_key_feedback_background_holo_width">46dp</dimen>
+    <dimen name="keyboard_key_feedback_background_holo_height">58dp</dimen>
+</resources>
diff --git a/java/res/values-xhdpi/keyboard_key_feedback_background_holo.xml b/java/res/values-xhdpi/keyboard_key_feedback_background_holo.xml
new file mode 100644
index 0000000..fba6026
--- /dev/null
+++ b/java/res/values-xhdpi/keyboard_key_feedback_background_holo.xml
@@ -0,0 +1,24 @@
+<?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>
+    <dimen name="keyboard_key_feedback_background_holo_width">47dp</dimen>
+    <dimen name="keyboard_key_feedback_background_holo_height">57dp</dimen>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 4dfa5ab..e569e83 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -88,6 +88,10 @@
         <attr name="keyPreviewLeftBackground" format="reference" />
         <!-- The background for the right edge key press feedback. -->
         <attr name="keyPreviewRightBackground" format="reference" />
+        <!-- The width of rectangle part of the key press feedback background. -->
+        <attr name="keyPreviewBackgroundWidth" format="dimension" />
+        <!-- The height of rectangle part of the key press feedback background. -->
+        <attr name="keyPreviewBackgroundHeight" format="dimension" />
         <!-- The text color for key press feedback. -->
         <attr name="keyPreviewTextColor" format="color" />
         <!-- Vertical offset of the key press feedback from the key. -->
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 30c0e5a..43aa583 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -259,6 +259,8 @@
         <item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
         <item name="keyPreviewLeftBackground">@drawable/keyboard_key_feedback_left_ics</item>
         <item name="keyPreviewRightBackground">@drawable/keyboard_key_feedback_right_ics</item>
+        <item name="keyPreviewBackgroundWidth">@dimen/keyboard_key_feedback_background_holo_width</item>
+        <item name="keyPreviewBackgroundHeight">@dimen/keyboard_key_feedback_background_holo_height</item>
         <item name="keyPreviewTextColor">#FFFFFFFF</item>
         <item name="keyPreviewHeight">@dimen/key_preview_height_ics</item>
         <item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
diff --git a/java/res/xml-sw600dp/kbd_rows_arabic.xml b/java/res/xml-sw600dp/kbd_rows_arabic.xml
index 275df50..c2d3cd4 100644
--- a/java/res/xml-sw600dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw600dp/kbd_rows_arabic.xml
@@ -26,30 +26,47 @@
     <Row
         latin:keyWidth="8.0%p"
     >
+        <!-- \u0636: ARABIC LETTER DAD -->
         <Key
             latin:keyLabel="ض" />
+        <!-- \u0635: ARABIC LETTER SAD -->
         <Key
             latin:keyLabel="ص" />
+        <!-- \u062b: ARABIC LETTER THEH -->
         <Key
             latin:keyLabel="ث" />
+        <!-- \u0642: ARABIC LETTER QAF
+             \u06a8: ARABIC LETTER QAF WITH THREE DOTS ABOVE -->
         <Key
-            latin:keyLabel="ق" />
+            latin:keyLabel="ق"
+            latin:moreKeys="ڨ" />
+        <!-- \u0641: ARABIC LETTER FEH
+             \u06a4: ARABIC LETTER VEH
+             \u06a2: ARABIC LETTER FEH WITH DOT MOVED BELOW
+             \u06a5: ARABIC LETTER FEH WITH THREE DOTS BELOW -->
         <Key
             latin:keyLabel="ف"
-            latin:moreKeys="ڤ" />
+            latin:moreKeys="\u06a4,\u06a2,\u06a5" />
+        <!-- \u063a: ARABIC LETTER GHAIN -->
         <Key
             latin:keyLabel="غ" />
+        <!-- \u0639: ARABIC LETTER AIN -->
         <Key
             latin:keyLabel="ع" />
-        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
-             \u0647\u0640: ARABIC LETTER HEH + ARABIC TATWEEL -->
+        <!-- \u0647: ARABIC LETTER HEH
+             \ufeeb: ARABIC LETTER HEH INITIAL FORM
+             \u0647\u0640: ARABIC LETTER HEH + Zero width joiner -->
         <Key
             latin:keyLabel="ه"
-            latin:moreKeys="\ufeeb|\u0647\u0640" />
+            latin:moreKeys="\ufeeb|\u0647\u200D" />
+        <!-- \u062e: ARABIC LETTER KHAH -->
         <Key
             latin:keyLabel="خ" />
+        <!-- \u062d: ARABIC LETTER HAH -->
         <Key
             latin:keyLabel="ح" />
+        <!-- \u062c: ARABIC LETTER JEEM
+             \u0686: ARABIC LETTER TCHEH -->
         <Key
             latin:keyLabel="ج"
             latin:moreKeys="چ" />
@@ -61,18 +78,28 @@
     <Row
         latin:keyWidth="8.0%p"
     >
+        <!-- \u0634: ARABIC LETTER SHEEN
+             \u069c: ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE -->
         <Key
             latin:keyLabel="ش"
+            latin:moreKeys="ڜ"
             latin:keyXPos="3.0%p" />
+        <!-- \u0633: ARABIC LETTER SEEN -->
         <Key
             latin:keyLabel="س" />
+        <!-- \u064a: ARABIC LETTER YEH
+             \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE
+             \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
-            latin:keyLabel="ي" />
+            latin:keyLabel="ي"
+            latin:moreKeys="\u0626,\u0649" />
+        <!-- \u0628: ARABIC LETTER BEH
+             \u067e: ARABIC LETTER PEH -->
         <Key
             latin:keyLabel="ب"
             latin:moreKeys="پ" />
-        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
-             \u0644: ARABIC LETTER LAM
+        <!-- \u0644: ARABIC LETTER LAM
+             \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
              \u0627: ARABIC LETTER ALEF
              \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
              \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
@@ -83,21 +110,31 @@
         <Key
             latin:keyLabel="ل"
             latin:moreKeys="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
-        <!-- \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+        <!-- \u0627: ARABIC LETTER ALEF
+             \u0621: ARABIC LETTER HAMZA
+             \u0671: ARABIC LETTER ALEF WASLA
+             \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:moreKeys="\u0623,\u0625,\u0622" />
+            latin:moreKeys="\u0621,\u0671,\u0623,\u0625,\u0622" />
+        <!-- \u062a: ARABIC LETTER TEH -->
         <Key
             latin:keyLabel="ت" />
+        <!-- \u0646: ARABIC LETTER NOON -->
         <Key
             latin:keyLabel="ن" />
+        <!-- \u0645: ARABIC LETTER MEEM -->
         <Key
             latin:keyLabel="م" />
+        <!-- \u0643: ARABIC LETTER KAF
+             \u06af: ARABIC LETTER GAF
+             \u06a9: ARABIC LETTER KEHEH -->
         <Key
             latin:keyLabel="ك"
-            latin:moreKeys="گ" />
+            latin:moreKeys="\u06af,\u06a9" />
+        <!-- \u0637: ARABIC LETTER TAH -->
         <Key
             latin:keyLabel="ط" />
         <Key
@@ -139,27 +176,39 @@
                     latin:keyStyle="smileyKeyStyle" />
             </default>
         </switch>
+        <!-- \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE -->
         <Key
             latin:keyLabel="ئ" />
+        <!-- \u0621: ARABIC LETTER HAMZA -->
         <Key
             latin:keyLabel="ء" />
+        <!-- \u0624: ARABIC LETTER WAW WITH HAMZA ABOVE -->
         <Key
             latin:keyLabel="ؤ" />
+        <!-- \u0631: ARABIC LETTER REH -->
         <Key
             latin:keyLabel="ر" />
+        <!-- \u0630: ARABIC LETTER THAL -->
         <Key
             latin:keyLabel="ذ" />
+        <!-- \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
             latin:keyLabel="ى" />
+        <!-- \u0629: ARABIC LETTER TEH MARBUTA -->
         <Key
             latin:keyLabel="ة" />
+        <!-- \u0648: ARABIC LETTER WAW -->
         <Key
             latin:keyLabel="و" />
+        <!-- \u0632: ARABIC LETTER ZAIN
+             \u0698: ARABIC LETTER JEH -->
         <Key
             latin:keyLabel="ز"
             latin:moreKeys="ژ" />
+        <!-- \u0638: ARABIC LETTER ZAH -->
         <Key
             latin:keyLabel="ظ" />
+        <!-- \u062f: ARABIC LETTER DAL -->
         <Key
             latin:keyLabel="د" />
     </Row>
diff --git a/java/res/xml-sw768dp/kbd_rows_arabic.xml b/java/res/xml-sw768dp/kbd_rows_arabic.xml
index 984ba50..7ec36fd 100644
--- a/java/res/xml-sw768dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw768dp/kbd_rows_arabic.xml
@@ -30,30 +30,47 @@
             latin:keyStyle="tabKeyStyle"
             latin:keyLabelOption="alignLeft"
             latin:keyWidth="7.500%p" />
+        <!-- \u0636: ARABIC LETTER DAD -->
         <Key
             latin:keyLabel="ض" />
+        <!-- \u0635: ARABIC LETTER SAD -->
         <Key
             latin:keyLabel="ص" />
+        <!-- \u062b: ARABIC LETTER THEH -->
         <Key
             latin:keyLabel="ث" />
+        <!-- \u0642: ARABIC LETTER QAF
+             \u06a8: ARABIC LETTER QAF WITH THREE DOTS ABOVE -->
         <Key
-            latin:keyLabel="ق" />
+            latin:keyLabel="ق"
+            latin:moreKeys="ڨ" />
+        <!-- \u0641: ARABIC LETTER FEH
+             \u06a4: ARABIC LETTER VEH
+             \u06a2: ARABIC LETTER FEH WITH DOT MOVED BELOW
+             \u06a5: ARABIC LETTER FEH WITH THREE DOTS BELOW -->
         <Key
             latin:keyLabel="ف"
-            latin:moreKeys="ڤ" />
+            latin:moreKeys="\u06a4,\u06a2,\u06a5" />
+        <!-- \u063a: ARABIC LETTER GHAIN -->
         <Key
             latin:keyLabel="غ" />
+        <!-- \u0639: ARABIC LETTER AIN -->
         <Key
             latin:keyLabel="ع" />
-        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
-             \u0647\u0640: ARABIC LETTER HEH + ARABIC TATWEEL -->
+        <!-- \u0647: ARABIC LETTER HEH
+             \ufeeb: ARABIC LETTER HEH INITIAL FORM
+             \u0647\u0640: ARABIC LETTER HEH + Zero width joiner -->
         <Key
             latin:keyLabel="ه"
-            latin:moreKeys="\ufeeb|\u0647\u0640" />
+            latin:moreKeys="\ufeeb|\u0647\u200D" />
+        <!-- \u062e: ARABIC LETTER KHAH -->
         <Key
             latin:keyLabel="خ" />
+        <!-- \u062d: ARABIC LETTER HAH -->
         <Key
             latin:keyLabel="ح" />
+        <!-- \u062c: ARABIC LETTER JEEM
+             \u0686: ARABIC LETTER TCHEH -->
         <Key
             latin:keyLabel="ج"
             latin:moreKeys="چ" />
@@ -69,17 +86,27 @@
             latin:keyStyle="toSymbolKeyStyle"
             latin:keyLabelOption="alignLeft"
             latin:keyWidth="9.375%p" />
+        <!-- \u0634: ARABIC LETTER SHEEN
+             \u069c: ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE -->
         <Key
-            latin:keyLabel="ش" />
+            latin:keyLabel="ش"
+            latin:moreKeys="ڜ" />
+        <!-- \u0633: ARABIC LETTER SEEN -->
         <Key
             latin:keyLabel="س" />
+        <!-- \u064a: ARABIC LETTER YEH
+             \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE
+             \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
-            latin:keyLabel="ي" />
+            latin:keyLabel="ي"
+            latin:moreKeys="\u0626,\u0649" />
+        <!-- \u0628: ARABIC LETTER BEH
+             \u067e: ARABIC LETTER PEH -->
         <Key
             latin:keyLabel="ب"
             latin:moreKeys="پ" />
-        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
-             \u0644: ARABIC LETTER LAM
+        <!-- \u0644: ARABIC LETTER LAM
+             \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
              \u0627: ARABIC LETTER ALEF
              \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
              \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
@@ -90,21 +117,30 @@
         <Key
             latin:keyLabel="ل"
             latin:moreKeys="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
-        <!-- \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
+        <!-- \u0627: ARABIC LETTER ALEF
+             \u0621: ARABIC LETTER HAMZA
+             \u0671: ARABIC LETTER ALEF WASLA
+             \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:moreKeys="\u0623,\u0625,\u0622" />
+            latin:moreKeys="\u0621,\u0671,\u0623,\u0625,\u0622" />
+        <!-- \u062a: ARABIC LETTER TEH -->
         <Key
             latin:keyLabel="ت" />
+        <!-- \u0646: ARABIC LETTER NOON -->
         <Key
             latin:keyLabel="ن" />
+        <!-- \u0645: ARABIC LETTER MEEM -->
         <Key
             latin:keyLabel="م" />
+        <!-- \u0643: ARABIC LETTER KAF
+             \u06af: ARABIC LETTER GAF -->
         <Key
             latin:keyLabel="ك"
             latin:moreKeys="گ" />
+        <!-- \u0637: ARABIC LETTER TAH -->
         <Key
             latin:keyLabel="ط" />
         <Key
@@ -115,28 +151,40 @@
     <Row
         latin:keyWidth="7.375%p"
     >
+        <!-- \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE -->
         <Key
             latin:keyLabel="ئ"
             latin:keyXPos="12.750%p" />
+        <!-- \u0621: ARABIC LETTER HAMZA -->
         <Key
             latin:keyLabel="ء" />
+        <!-- \u0624: ARABIC LETTER WAW WITH HAMZA ABOVE -->
         <Key
             latin:keyLabel="ؤ" />
+        <!-- \u0631: ARABIC LETTER REH -->
         <Key
             latin:keyLabel="ر" />
+        <!-- \u0630: ARABIC LETTER THAL -->
         <Key
             latin:keyLabel="ذ" />
+        <!-- \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
             latin:keyLabel="ى" />
+        <!-- \u0629: ARABIC LETTER TEH MARBUTA -->
         <Key
             latin:keyLabel="ة" />
+        <!-- \u0648: ARABIC LETTER WAW -->
         <Key
             latin:keyLabel="و" />
+        <!-- \u0632: ARABIC LETTER ZAIN
+             \u0698: ARABIC LETTER JEH -->
         <Key
             latin:keyLabel="ز"
             latin:moreKeys="ژ" />
+        <!-- \u0638: ARABIC LETTER ZAH -->
         <Key
             latin:keyLabel="ظ" />
+        <!-- \u062f: ARABIC LETTER DAL -->
         <Key
             latin:keyLabel="د" />
     </Row>
diff --git a/java/res/xml/kbd_rows_arabic.xml b/java/res/xml/kbd_rows_arabic.xml
index fba7271..dd5123e 100644
--- a/java/res/xml/kbd_rows_arabic.xml
+++ b/java/res/xml/kbd_rows_arabic.xml
@@ -26,69 +26,89 @@
     <Row
         latin:keyWidth="10%p"
     >
+        <!-- \u0636: ARABIC LETTER DAD -->
         <Key
             latin:keyLabel="ض"
-            latin:keyHintLabel="١"
-            latin:moreKeys="١,1" />
+            latin:keyHintLabel="1"
+            latin:moreKeys="1,١" />
+        <!-- \u0635: ARABIC LETTER SAD -->
         <Key
             latin:keyLabel="ص"
-            latin:keyHintLabel="٢"
-            latin:moreKeys="٢,2" />
+            latin:keyHintLabel="2"
+            latin:moreKeys="2,٢" />
+        <!-- \u0642: ARABIC LETTER QAF
+             \u06a8: ARABIC LETTER QAF WITH THREE DOTS ABOVE -->
         <Key
             latin:keyLabel="ق"
-            latin:keyHintLabel="٣"
-            latin:moreKeys="٣,3" />
-        <!-- \u06a4: ARABIC LETTER VEH -->
+            latin:keyHintLabel="3"
+            latin:moreKeys="3,٣,\u06a8" />
+        <!-- \u0641: ARABIC LETTER FEH
+             \u06a4: ARABIC LETTER VEH
+             \u06a2: ARABIC LETTER FEH WITH DOT MOVED BELOW
+             \u06a5: ARABIC LETTER FEH WITH THREE DOTS BELOW -->
         <Key
             latin:keyLabel="ف"
-            latin:keyHintLabel="٤"
-            latin:moreKeys="٤,4,\u06a4" />
+            latin:keyHintLabel="4"
+            latin:moreKeys="4,٤,\u06a4,\u06a2,\u06a5" />
+        <!-- \u063a: ARABIC LETTER GHAIN -->
         <Key
             latin:keyLabel="غ"
-            latin:keyHintLabel="٥"
-            latin:moreKeys="٥,5" />
+            latin:keyHintLabel="5"
+            latin:moreKeys="5,٥" />
+        <!-- \u0639: ARABIC LETTER AIN -->
         <Key
             latin:keyLabel="ع"
-            latin:keyHintLabel="٦"
-            latin:moreKeys="٦,6" />
-        <!-- \ufeeb: ARABIC LETTER HEH INITIAL FORM
+            latin:keyHintLabel="6"
+            latin:moreKeys="6,٦" />
+        <!-- \u0647: ARABIC LETTER HEH
+             \ufeeb: ARABIC LETTER HEH INITIAL FORM
              \u0647\u0640: ARABIC LETTER HEH + Zero width joiner -->
         <Key
             latin:keyLabel="ه"
-            latin:keyHintLabel="٧"
-            latin:moreKeys="٧,7,\ufeeb|\u0647\u200D" />
+            latin:keyHintLabel="7"
+            latin:moreKeys="7,٧,\ufeeb|\u0647\u200D" />
+        <!-- \u062e: ARABIC LETTER KHAH -->
         <Key
             latin:keyLabel="خ"
-            latin:keyHintLabel="٨"
-            latin:moreKeys="٨,8" />
+            latin:keyHintLabel="8"
+            latin:moreKeys="8,٨" />
+        <!-- \u062d: ARABIC LETTER HAH -->
         <Key
             latin:keyLabel="ح"
-            latin:keyHintLabel="٩"
-            latin:moreKeys="٩,9" />
-        <!-- \u0686: ARABIC LETTER TCHEH -->
+            latin:keyHintLabel="9"
+            latin:moreKeys="9,٩" />
+        <!-- \u062c: ARABIC LETTER JEEM
+             \u0686: ARABIC LETTER TCHEH -->
         <Key
             latin:keyLabel="ج"
-            latin:keyHintLabel="٠"
-            latin:moreKeys="٠,0,\u0686"
+            latin:keyHintLabel="0"
+            latin:moreKeys="0,٠,\u0686"
             latin:keyWidth="fillRight" />
     </Row>
     <Row
         latin:keyWidth="10%p"
     >
+        <!-- \u0634: ARABIC LETTER SHEEN
+             \u069c: ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE -->
         <Key
-            latin:keyLabel="ش" />
+            latin:keyLabel="ش"
+            latin:moreKeys="ڜ" />
+        <!-- \u0633: ARABIC LETTER SEEN -->
         <Key
             latin:keyLabel="س" />
-        <!-- \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE
+        <!-- \u064a: ARABIC LETTER YEH
+             \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE
              \u0649: ARABIC LETTER ALEF MAKSURA -->
         <Key
             latin:keyLabel="ي"
             latin:moreKeys="\u0626,\u0649" />
+        <!-- \u0628: ARABIC LETTER BEH
+             \u067e: ARABIC LETTER PEH -->
         <Key
             latin:keyLabel="ب"
             latin:moreKeys="پ" />
-        <!-- \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
-             \u0644: ARABIC LETTER LAM
+        <!-- \u0644: ARABIC LETTER LAM
+             \ufefb: ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
              \u0627: ARABIC LETTER ALEF
              \ufef7: ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
              \u0623: ARABIC LETTER ALEF WITH HAMZA ABOVE
@@ -99,44 +119,63 @@
         <Key
             latin:keyLabel="ل"
             latin:moreKeys="\ufefb|\u0644\u0627,\ufef7|\u0644\u0623,\ufef9|\u0644\u0625,\ufef5|\u0644\u0622" />
-        <!-- \u0621: ARABIC LETTER HAMZA
+        <!-- \u0627: ARABIC LETTER ALEF
+             \u0621: ARABIC LETTER HAMZA
+             \u0671: ARABIC LETTER ALEF WASLA
              \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:moreKeys="\u0621,\u0623,\u0625,\u0622" />
+            latin:moreKeys="\u0621,\u0671,\u0623,\u0625,\u0622" />
+        <!-- \u062a: ARABIC LETTER TEH
+             \u062b: ARABIC LETTER THEH -->
         <Key
             latin:keyLabel="ت"
             latin:moreKeys="ث" />
+        <!-- \u0646: ARABIC LETTER NOON -->
         <Key
             latin:keyLabel="ن" />
+        <!-- \u0645: ARABIC LETTER MEEM -->
         <Key
             latin:keyLabel="م" />
+        <!-- \u0643: ARABIC LETTER KAF
+             \u06af: ARABIC LETTER GAF
+             \u06a9: ARABIC LETTER KEHEH -->
         <Key
             latin:keyLabel="ك"
-            latin:moreKeys="گ"
+            latin:moreKeys="\u06af,\u06a9"
             latin:keyWidth="fillRight" />
     </Row>
     <Row
         latin:keyWidth="10%p"
     >
+        <!-- \u0638: ARABIC LETTER ZAH -->
         <Key
             latin:keyLabel="ظ"
             latin:keyXPos="5.0%p" />
+        <!-- \u0637: ARABIC LETTER TAH -->
         <Key
             latin:keyLabel="ط" />
+        <!-- \u0630: ARABIC LETTER THAL -->
         <Key
             latin:keyLabel="ذ" />
+        <!-- \u062f: ARABIC LETTER DAL -->
         <Key
             latin:keyLabel="د" />
+        <!-- \u0632: ARABIC LETTER ZAIN
+             \u0698: ARABIC LETTER JEH -->
         <Key
             latin:keyLabel="ز"
             latin:moreKeys="ژ" />
+        <!-- \u0631: ARABIC LETTER REH -->
         <Key
             latin:keyLabel="ر" />
+        <!-- \u0629: ARABIC LETTER TEH MARBUTA -->
         <Key
             latin:keyLabel="ة" />
+        <!-- \u0648: ARABIC LETTER WAW
+             \u0624: ARABIC LETTER WAW WITH HAMZA ABOVE -->
         <Key
             latin:keyLabel="و"
             latin:moreKeys="ؤ" />
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 876bd65..2766cc3 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -69,7 +69,8 @@
             Log.w(TAG, "Suggestion span was not created.");
             return text;
         }
-        spannable.setSpan(ss, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        spannable.setSpan(ss, 0, text.length(),
+                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
         return spannable;
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 6af4123..04e6725 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -100,7 +100,7 @@
 
     // Key preview
     private final int mKeyPreviewLayoutId;
-    private final KeyPreviewDrawParams mKeyPreviewDrawParams;
+    protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
     private boolean mShowKeyPreviewPopup = true;
     private final int mDelayBeforePreview;
     private int mDelayAfterPreview;
@@ -284,11 +284,13 @@
         }
     }
 
-    private static class KeyPreviewDrawParams {
+    protected static class KeyPreviewDrawParams {
         // XML attributes.
         public final Drawable mPreviewBackground;
         public final Drawable mPreviewLeftBackground;
         public final Drawable mPreviewRightBackground;
+        public final int mPreviewBackgroundWidth;
+        public final int mPreviewBackgroundHeight;
         public final int mPreviewTextColor;
         public final int mPreviewOffset;
         public final int mPreviewHeight;
@@ -312,6 +314,10 @@
             setAlpha(mPreviewBackground, PREVIEW_ALPHA);
             setAlpha(mPreviewLeftBackground, PREVIEW_ALPHA);
             setAlpha(mPreviewRightBackground, PREVIEW_ALPHA);
+            mPreviewBackgroundWidth = a.getDimensionPixelSize(
+                    R.styleable.KeyboardView_keyPreviewBackgroundWidth, 0);
+            mPreviewBackgroundHeight = a.getDimensionPixelSize(
+                    R.styleable.KeyboardView_keyPreviewBackgroundHeight, 0);
             mPreviewOffset = a.getDimensionPixelOffset(
                     R.styleable.KeyboardView_keyPreviewOffset, 0);
             mPreviewHeight = a.getDimensionPixelSize(
@@ -974,5 +980,9 @@
         if (mPreviewPlacer != null) {
             mPreviewPlacer.removeAllViews();
         }
+        if (mBuffer != null) {
+            mBuffer.recycle();
+            mBuffer = null;
+        }
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 3452720..c51f184 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -59,8 +59,8 @@
     private final int mSpacebarTextColor;
     private final int mSpacebarTextShadowColor;
     private float mSpacebarTextFadeFactor = 0.0f;
-    private final HashMap<Integer, SoftReference<BitmapDrawable>> mSpaceDrawableCache =
-            new HashMap<Integer, SoftReference<BitmapDrawable>>();
+    private final HashMap<Integer, BitmapDrawable> mSpaceDrawableCache =
+            new HashMap<Integer, BitmapDrawable>();
     private final boolean mIsSpacebarTriggeringPopupByLongPress;
 
     /* Shortcut key and its icons if available */
@@ -249,13 +249,13 @@
     private BitmapDrawable getSpaceDrawable(Locale locale, boolean isAutoCorrection) {
         final Integer hashCode = Arrays.hashCode(
                 new Object[] { locale, isAutoCorrection, mSpacebarTextFadeFactor });
-        final SoftReference<BitmapDrawable> ref = mSpaceDrawableCache.get(hashCode);
-        BitmapDrawable drawable = (ref == null) ? null : ref.get();
-        if (drawable == null) {
-            drawable = new BitmapDrawable(mRes, drawSpacebar(
-                    locale, isAutoCorrection, mSpacebarTextFadeFactor));
-            mSpaceDrawableCache.put(hashCode, new SoftReference<BitmapDrawable>(drawable));
+        final BitmapDrawable cached = mSpaceDrawableCache.get(hashCode);
+        if (cached != null) {
+            return cached;
         }
+        final BitmapDrawable drawable = new BitmapDrawable(mRes, drawSpacebar(
+                locale, isAutoCorrection, mSpacebarTextFadeFactor));
+        mSpaceDrawableCache.put(hashCode, drawable);
         return drawable;
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index d4b35a5..ac9290b 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -215,10 +215,21 @@
             mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
             mMoreKeys = parentKey.mMoreKeys;
 
-            final int keyWidth = getMaxKeyWidth(view, mMoreKeys, mParams.mDefaultKeyWidth);
-            mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn,
-                    keyWidth, parentKeyboard.mMostCommonKeyHeight, parentKey.mX
-                            + (mParams.mDefaultKeyWidth - keyWidth) / 2, view.getMeasuredWidth());
+            final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth;
+            final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight;
+            final int width, height;
+            // Use pre-computed width and height if these values are available and mini keyboard
+            // has only one key to mitigate visual flicker between key preview and mini keyboard.
+            if (view.isKeyPreviewPopupEnabled() && mMoreKeys.length == 1 && previewWidth > 0
+                    && previewHeight > 0) {
+                width = previewWidth;
+                height = previewHeight + mParams.mVerticalGap;
+            } else {
+                width = getMaxKeyWidth(view, parentKey.mMoreKeys, mParams.mDefaultKeyWidth);
+                height = parentKeyboard.mMostCommonKeyHeight;
+            }
+            mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn, width, height,
+                    parentKey.mX + (mParams.mDefaultKeyWidth - width) / 2, view.getMeasuredWidth());
         }
 
         private static int getMaxKeyWidth(KeyboardView view, CharSequence[] moreKeys,
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 70e37a9..517385c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1038,17 +1038,8 @@
 
     @Override
     public boolean onEvaluateFullscreenMode() {
-        if (!super.onEvaluateFullscreenMode()) return false;
-
-        final EditorInfo ei = getCurrentInputEditorInfo();
-        if (ei != null) {
-            final int imeOptions = ei.imeOptions;
-            if ((imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0) {
-                return false;
-            }
-        }
-
-        return mResources.getBoolean(R.bool.config_use_fullscreen_mode);
+        return super.onEvaluateFullscreenMode()
+                && mResources.getBoolean(R.bool.config_use_fullscreen_mode);
     }
 
     @Override
diff --git a/native/src/correction.cpp b/native/src/correction.cpp
index 31493ee..0c56680 100644
--- a/native/src/correction.cpp
+++ b/native/src/correction.cpp
@@ -27,6 +27,87 @@
 
 namespace latinime {
 
+/////////////////////////////
+// edit distance funcitons //
+/////////////////////////////
+
+#if 0 /* no longer used */
+inline static int editDistance(
+        int* editDistanceTable, const unsigned short* input,
+        const int inputLength, const unsigned short* output, const int outputLength) {
+    // dp[li][lo] dp[a][b] = dp[ a * lo + b]
+    int* dp = editDistanceTable;
+    const int li = inputLength + 1;
+    const int lo = outputLength + 1;
+    for (int i = 0; i < li; ++i) {
+        dp[lo * i] = i;
+    }
+    for (int i = 0; i < lo; ++i) {
+        dp[i] = i;
+    }
+
+    for (int i = 0; i < li - 1; ++i) {
+        for (int j = 0; j < lo - 1; ++j) {
+            const uint32_t ci = Dictionary::toBaseLowerCase(input[i]);
+            const uint32_t co = Dictionary::toBaseLowerCase(output[j]);
+            const uint16_t cost = (ci == co) ? 0 : 1;
+            dp[(i + 1) * lo + (j + 1)] = min(dp[i * lo + (j + 1)] + 1,
+                    min(dp[(i + 1) * lo + j] + 1, dp[i * lo + j] + cost));
+            if (i > 0 && j > 0 && ci == Dictionary::toBaseLowerCase(output[j - 1])
+                    && co == Dictionary::toBaseLowerCase(input[i - 1])) {
+                dp[(i + 1) * lo + (j + 1)] = min(
+                        dp[(i + 1) * lo + (j + 1)], dp[(i - 1) * lo + (j - 1)] + cost);
+            }
+        }
+    }
+
+    if (DEBUG_EDIT_DISTANCE) {
+        LOGI("IN = %d, OUT = %d", inputLength, outputLength);
+        for (int i = 0; i < li; ++i) {
+            for (int j = 0; j < lo; ++j) {
+                LOGI("EDIT[%d][%d], %d", i, j, dp[i * lo + j]);
+            }
+        }
+    }
+    return dp[li * lo - 1];
+}
+#endif
+
+inline static void initEditDistance(int *editDistanceTable) {
+    for (int i = 0; i <= MAX_WORD_LENGTH_INTERNAL; ++i) {
+        editDistanceTable[i] = i;
+    }
+}
+
+inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigned short *input,
+        const int inputLength, const unsigned short *output, const int outputLength) {
+    // Let dp[i][j] be editDistanceTable[i * (inputLength + 1) + j].
+    // Assuming that dp[0][0] ... dp[outputLength - 1][inputLength] are already calculated,
+    // and calculate dp[ouputLength][0] ... dp[outputLength][inputLength].
+    int *const current = editDistanceTable + outputLength * (inputLength + 1);
+    const int *const prev = editDistanceTable + (outputLength - 1) * (inputLength + 1);
+    const int *const prevprev =
+            outputLength >= 2 ? editDistanceTable + (outputLength - 2) * (inputLength + 1) : NULL;
+    current[0] = outputLength;
+    const uint32_t co = Dictionary::toBaseLowerCase(output[outputLength - 1]);
+    const uint32_t prevCO =
+            outputLength >= 2 ? Dictionary::toBaseLowerCase(output[outputLength - 2]) : 0;
+    for (int i = 1; i <= inputLength; ++i) {
+        const uint32_t ci = Dictionary::toBaseLowerCase(input[i - 1]);
+        const uint16_t cost = (ci == co) ? 0 : 1;
+        current[i] = min(current[i - 1] + 1, min(prev[i] + 1, prev[i - 1] + cost));
+        if (i >= 2 && prevprev && ci == prevCO
+                && co == Dictionary::toBaseLowerCase(input[i - 2])) {
+            current[i] = min(current[i], prevprev[i - 2] + 1);
+        }
+    }
+}
+
+inline static int getCurrentEditDistance(
+        int *editDistanceTable, const int inputLength, const int outputLength) {
+    return editDistanceTable[(inputLength + 1) * (outputLength + 1) - 1];
+}
+
 //////////////////////
 // inline functions //
 //////////////////////
@@ -43,6 +124,7 @@
 
 Correction::Correction(const int typedLetterMultiplier, const int fullWordMultiplier)
         : TYPED_LETTER_MULTIPLIER(typedLetterMultiplier), FULL_WORD_MULTIPLIER(fullWordMultiplier) {
+    initEditDistance(mEditDistanceTable);
 }
 
 void Correction::initCorrection(const ProximityInfo *pi, const int inputLength,
@@ -197,13 +279,21 @@
 }
 
 bool Correction::needsToPrune() const {
+    // TODO: use edit distance here
     return mOutputIndex - 1 >= mMaxDepth || mProximityCount > mMaxEditDistance;
 }
 
+void Correction::addCharToCurrentWord(const int32_t c) {
+    mWord[mOutputIndex] = c;
+    const unsigned short *primaryInputWord = mProximityInfo->getPrimaryInputWord();
+    calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputLength,
+            mWord, mOutputIndex + 1);
+}
+
 // TODO: inline?
 Correction::CorrectionType Correction::processSkipChar(
         const int32_t c, const bool isTerminal, const bool inputIndexIncremented) {
-    mWord[mOutputIndex] = c;
+    addCharToCurrentWord(c);
     if (needsToTraverseAllNodes() && isTerminal) {
         mTerminalInputIndex = mInputIndex - (inputIndexIncremented ? 1 : 0);
         mTerminalOutputIndex = mOutputIndex;
@@ -412,7 +502,7 @@
                 mProximityInfo->getNormalizedSquaredDistance(mInputIndex, proximityIndex);
     }
 
-    mWord[mOutputIndex] = c;
+    addCharToCurrentWord(c);
 
     // 4. Last char excessive correction
     mLastCharExceeded = mExcessiveCount == 0 && mSkippedCount == 0 && mTransposedCount == 0
@@ -526,47 +616,6 @@
      return false;
 }
 
-/* static */
-inline static int editDistance(
-        int* editDistanceTable, const unsigned short* input,
-        const int inputLength, const unsigned short* output, const int outputLength) {
-    // dp[li][lo] dp[a][b] = dp[ a * lo + b]
-    int* dp = editDistanceTable;
-    const int li = inputLength + 1;
-    const int lo = outputLength + 1;
-    for (int i = 0; i < li; ++i) {
-        dp[lo * i] = i;
-    }
-    for (int i = 0; i < lo; ++i) {
-        dp[i] = i;
-    }
-
-    for (int i = 0; i < li - 1; ++i) {
-        for (int j = 0; j < lo - 1; ++j) {
-            const uint32_t ci = Dictionary::toBaseLowerCase(input[i]);
-            const uint32_t co = Dictionary::toBaseLowerCase(output[j]);
-            const uint16_t cost = (ci == co) ? 0 : 1;
-            dp[(i + 1) * lo + (j + 1)] = min(dp[i * lo + (j + 1)] + 1,
-                    min(dp[(i + 1) * lo + j] + 1, dp[i * lo + j] + cost));
-            if (i > 0 && j > 0 && ci == Dictionary::toBaseLowerCase(output[j - 1])
-                    && co == Dictionary::toBaseLowerCase(input[i - 1])) {
-                dp[(i + 1) * lo + (j + 1)] = min(
-                        dp[(i + 1) * lo + (j + 1)], dp[(i - 1) * lo + (j - 1)] + cost);
-            }
-        }
-    }
-
-    if (DEBUG_EDIT_DISTANCE) {
-        LOGI("IN = %d, OUT = %d", inputLength, outputLength);
-        for (int i = 0; i < li; ++i) {
-            for (int j = 0; j < lo; ++j) {
-                LOGI("EDIT[%d][%d], %d", i, j, dp[i * lo + j]);
-            }
-        }
-    }
-    return dp[li * lo - 1];
-}
-
 //////////////////////
 // RankingAlgorithm //
 //////////////////////
@@ -612,9 +661,7 @@
     // TODO: Optimize this.
     // TODO: Ignoring edit distance for transposed char, for now
     if (transposedCount == 0 && (proximityMatchedCount > 0 || skipped || excessiveCount > 0)) {
-        const unsigned short* primaryInputWord = proximityInfo->getPrimaryInputWord();
-        ed = editDistance(editDistanceTable, primaryInputWord,
-                inputLength, word, outputIndex + 1);
+        ed = getCurrentEditDistance(editDistanceTable, inputLength, outputIndex + 1);
         const int matchWeight = powerIntCapped(typedLetterMultiplier,
                 max(inputLength, outputIndex + 1) - ed);
         multiplyIntCapped(matchWeight, &finalFreq);
diff --git a/native/src/correction.h b/native/src/correction.h
index 437ef77..d4e99f0 100644
--- a/native/src/correction.h
+++ b/native/src/correction.h
@@ -102,6 +102,7 @@
     inline bool isQuote(const unsigned short c);
     inline CorrectionType processSkipChar(
             const int32_t c, const bool isTerminal, const bool inputIndexIncremented);
+    inline void addCharToCurrentWord(const int32_t c);
 
     const int TYPED_LETTER_MULTIPLIER;
     const int FULL_WORD_MULTIPLIER;