Merge "Key release event should be sent when finger sliding"
diff --git a/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml b/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml
index 87e952c..6c27136 100644
--- a/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml
+++ b/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml
@@ -17,5 +17,4 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
           android:drawable="@drawable/btn_keyboard_key_popup_selected_holo" />
-    <item android:drawable="@drawable/btn_keyboard_key_light_popup_normal" />
 </selector>
diff --git a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml
index 50e91f7..5a91dbe 100644
--- a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml
+++ b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml
@@ -23,8 +23,8 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:background="@drawable/keyboard_popup_panel_background_holo"
-        android:paddingLeft="44dip"
-        android:paddingRight="32dip"
+        android:paddingLeft="40dip"
+        android:paddingRight="40dip"
         >
     <com.android.inputmethod.latin.BaseKeyboardView
             xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
diff --git a/java/res/layout/input_gingerbread.xml b/java/res/layout/input_gingerbread.xml
index 1991083..fe31321 100644
--- a/java/res/layout/input_gingerbread.xml
+++ b/java/res/layout/input_gingerbread.xml
@@ -28,8 +28,7 @@
         android:paddingTop="@dimen/keyboard_top_padding"
         android:paddingBottom="@dimen/keyboard_bottom_padding"
         android:background="@drawable/keyboard_dark_background"
-        android:textStyle="bold"
 
         latin:keyBackground="@drawable/btn_keyboard_key_gingerbread"
-        latin:keyTextStyle="bold"
+        latin:keyLetterStyle="bold"
         />
diff --git a/java/res/layout/input_honeycomb.xml b/java/res/layout/input_honeycomb.xml
index 79eb7be..079e70c 100644
--- a/java/res/layout/input_honeycomb.xml
+++ b/java/res/layout/input_honeycomb.xml
@@ -28,10 +28,12 @@
         android:paddingTop="@dimen/keyboard_top_padding"
         android:paddingBottom="@dimen/keyboard_bottom_padding"
         android:background="@drawable/keyboard_background_holo"
-        android:textStyle="bold"
 
         latin:keyBackground="@drawable/btn_keyboard_key_honeycomb"
         latin:keyPreviewLayout="@layout/key_preview_honeycomb"
         latin:popupLayout="@layout/keyboard_popup_honeycomb"
-        latin:keyTextStyle="bold"
+        latin:keyTextColorDisabled="#FF353535"
+        latin:keyLetterStyle="bold"
+        latin:shadowColor="#00000000"
+        latin:shadowRadius="0.0"
         />
diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml
index 2d4e0b2..5fb439a 100644
--- a/java/res/layout/input_stone_bold.xml
+++ b/java/res/layout/input_stone_bold.xml
@@ -26,12 +26,11 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/keyboard_background"
-        android:textStyle="bold"
 
         latin:keyBackground="@drawable/btn_keyboard_key_stone"
         latin:keyTextColor="@color/latinkeyboard_key_color_black"
         latin:shadowColor="@color/latinkeyboard_key_color_white"
-        latin:keyTextStyle="bold"
+        latin:keyLetterStyle="bold"
         latin:colorScheme="black"
         latin:popupLayout="@layout/input_stone_popup"
         />
diff --git a/java/res/values-xlarge-land/dimens.xml b/java/res/values-xlarge-land/dimens.xml
new file mode 100644
index 0000000..45d6dfa
--- /dev/null
+++ b/java/res/values-xlarge-land/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+    <dimen name="key_label_text_size">18dip</dimen>
+    <!-- left or right padding of label alignment -->
+    <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+</resources>
diff --git a/java/res/values-xlarge/bools.xml b/java/res/values-xlarge/bools.xml
index 66cfd9d..8c68d9d 100644
--- a/java/res/values-xlarge/bools.xml
+++ b/java/res/values-xlarge/bools.xml
@@ -21,4 +21,5 @@
     <!-- Whether or not Popup on key press is enabled by default -->
     <bool name="default_popup_preview">false</bool>
     <bool name="config_enable_show_settings_key_option">false</bool>
+    <bool name="config_enable_show_voice_key_option">false</bool>
 </resources>
diff --git a/java/res/values-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml
index 58fea4e..ecf8709 100644
--- a/java/res/values-xlarge/dimens.xml
+++ b/java/res/values-xlarge/dimens.xml
@@ -23,7 +23,7 @@
     <dimen name="key_height">13.0mm</dimen>
     <dimen name="key_bottom_gap">1.5mm</dimen>
     <dimen name="key_horizontal_gap">2.0mm</dimen>
-    <dimen name="popup_key_height">15.0mm</dimen>
+    <dimen name="popup_key_height">13.0mm</dimen>
     <dimen name="keyboard_top_padding">1.0mm</dimen>
     <dimen name="keyboard_bottom_padding">1.0mm</dimen>
     <!-- key_height x 1.0 -->
@@ -34,11 +34,11 @@
     <!-- popup_key_height x -1.0 -->
     <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
 
-    <dimen name="key_text_size">24dip</dimen>
-    <dimen name="key_label_text_size">18dip</dimen>
+    <dimen name="key_letter_size">24dip</dimen>
+    <dimen name="key_label_text_size">14dip</dimen>
     <dimen name="key_preview_text_size_large">24dip</dimen>
-    <!-- left or right padding for of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+    <!-- left or right padding of label alignment -->
+    <dimen name="key_label_horizontal_alignment_padding">4dip</dimen>
 
     <dimen name="candidate_strip_height">46dip</dimen>
 </resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index ee4ec05..ef7a968 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -25,8 +25,8 @@
              checkable+checked+pressed. -->
         <attr name="keyBackground" format="reference" />
 
-        <!-- Size of the text for character keys. -->
-        <attr name="keyTextSize" format="dimension" />
+        <!-- Size of the text for one letter character keys. -->
+        <attr name="keyLetterSize" format="dimension" />
 
         <!-- Size of the text for custom keys with some text and no icon. -->
         <attr name="labelTextSize" format="dimension" />
@@ -34,6 +34,9 @@
         <!-- Color to use for the label in a key. -->
         <attr name="keyTextColor" format="color" />
 
+        <!-- Color to use for the label in a key when in disabled state. -->
+        <attr name="keyTextColorDisabled" format="color" />
+
         <!-- Layout resource for key press feedback.-->
         <attr name="keyPreviewLayout" format="reference" />
 
@@ -56,10 +59,12 @@
         <attr name="shadowRadius" format="float" />
         <attr name="backgroundDimAmount" format="float" />
 
-        <attr name="keyTextStyle">
+        <attr name="keyLetterStyle">
+            <!-- This should be aligned with Typeface.NORMAL etc. -->
             <enum name="normal" value="0" />
             <enum name="bold" value="1" />
             <enum name="italic" value="2" />
+            <enum name="boldItalic" value="3" />
         </attr>
 
         <attr name="colorScheme">
diff --git a/java/res/values/bools.xml b/java/res/values/bools.xml
index 64d05bd..2be9545 100644
--- a/java/res/values/bools.xml
+++ b/java/res/values/bools.xml
@@ -31,4 +31,5 @@
     <bool name="default_recorrection_enabled">true</bool>
     <bool name="config_long_press_comma_for_settings_enabled">true</bool>
     <bool name="config_enable_show_settings_key_option">true</bool>
+    <bool name="config_enable_show_voice_key_option">true</bool>
 </resources>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index f29bc4d..3839ff0 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -34,10 +34,10 @@
     <!-- popup_key_height x -1.0 -->
     <dimen name="mini_keyboard_vertical_correction">-0.325in</dimen>
 
-    <dimen name="key_text_size">0.13in</dimen>
+    <dimen name="key_letter_size">0.13in</dimen>
     <dimen name="key_label_text_size">0.083in</dimen>
     <dimen name="key_preview_text_size_large">40sp</dimen>
-    <!-- left or right padding for of label alignment -->
+    <!-- left or right padding of label alignment -->
     <dimen name="key_label_horizontal_alignment_padding">0.13in</dimen>
     <dimen name="key_preview_offset">0.000in</dimen>
     <!-- We use "inch", not "dip" because this value tries dealing with physical distance related
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index ff22098..63c9f42 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -248,15 +248,15 @@
     
     <!-- Message of the warning dialog that shows when a user initiates voice input for
          the first time, or turns it on in settings. -->
-    <string name="voice_warning_may_not_understand">Voice input is an experimental feature using Google\'s networked speech recognition.</string>
+    <string name="voice_warning_may_not_understand">Voice input uses Google\'s speech recognition. <a href="http://m.google.com/privacy">The Mobile Privacy Policy</a> applies.</string>
     
     <!-- An additional part of the warning dialog for voice input that only shows when the user
          actually initiates voice input, rather than just turning it on in settings. -->
-    <string name="voice_warning_how_to_turn_off">To turn off voice input, go to keyboard settings.</string>
-    
-    <!-- Message to show when user clicks the swiping hint (which says
-        "Swipe across keyboard to speak"). Also shown when enabling settings. -->
-    <string name="voice_hint_dialog_message">To use voice input, press the microphone button or slide your finger across the on-screen keyboard.</string>
+    <string name="voice_warning_how_to_turn_off">To turn off voice input, go to input method settings.</string>
+
+    <!-- Message to show when user enables the voice input settings (which says
+        "Press the microphone button"). -->
+    <string name="voice_hint_dialog_message">To use voice input, press the microphone button.</string>
     
     <!-- Short message to tell the user the system is ready for them to speak. -->
     <string name="voice_listening">Speak now</string>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 6ab4ded..02d21b4 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -19,8 +19,10 @@
         <item name="android:background">@drawable/keyboard_background</item>
 
         <item name="keyBackground">@drawable/btn_keyboard_key</item>
-        <item name="keyTextSize">@dimen/key_text_size</item>
+        <item name="keyLetterSize">@dimen/key_letter_size</item>
+        <item name="keyLetterStyle">normal</item>
         <item name="keyTextColor">#FFFFFFFF</item>
+        <item name="keyTextColorDisabled">#FFFFFFFF</item>
         <item name="keyPreviewLayout">@layout/key_preview</item>
         <item name="keyPreviewOffset">@dimen/key_preview_offset</item>
         <item name="keyPreviewHeight">@dimen/key_preview_height</item>
diff --git a/java/res/xml-xlarge-land/kbd_popup_template.xml b/java/res/xml-xlarge-land/kbd_popup_template.xml
index 5fe9f67..fd348f2 100644
--- a/java/res/xml-xlarge-land/kbd_popup_template.xml
+++ b/java/res/xml-xlarge-land/kbd_popup_template.xml
@@ -19,9 +19,9 @@
 -->
 
 <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="5.0%p"
-    latin:horizontalGap="@dimen/key_horizontal_gap"
+    latin:keyWidth="3.5%p"
+    latin:horizontalGap="0px"
     latin:verticalGap="0px"
-    latin:keyHeight="@dimen/key_height"
+    latin:keyHeight="@dimen/popup_key_height"
     >
 </Keyboard>
diff --git a/java/res/xml-xlarge-land/popup_domains.xml b/java/res/xml-xlarge-land/popup_domains.xml
index 9ed79c8..deedba4 100644
--- a/java/res/xml-xlarge-land/popup_domains.xml
+++ b/java/res/xml-xlarge-land/popup_domains.xml
@@ -20,7 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="5.0%p"
+    latin:keyWidth="4.0%p"
     latin:horizontalGap="0px"
     latin:verticalGap="0px"
     latin:keyHeight="@dimen/popup_key_height"
diff --git a/java/res/xml-xlarge-land/popup_smileys.xml b/java/res/xml-xlarge-land/popup_smileys.xml
index bdd6805..e882a50 100644
--- a/java/res/xml-xlarge-land/popup_smileys.xml
+++ b/java/res/xml-xlarge-land/popup_smileys.xml
@@ -20,7 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="5.0%p"
+    latin:keyWidth="4.0%p"
     latin:horizontalGap="0px"
     latin:verticalGap="0px"
     latin:keyHeight="@dimen/popup_key_height"
diff --git a/java/res/xml-xlarge/kbd_phone.xml b/java/res/xml-xlarge/kbd_phone.xml
index 483b022..1e66102 100644
--- a/java/res/xml-xlarge/kbd_phone.xml
+++ b/java/res/xml-xlarge/kbd_phone.xml
@@ -65,7 +65,6 @@
     <Row>
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignLeft"
             latin:keyEdgeFlags="left" />
         <!-- To match one character label size with "More", I placed spaces around the char ','
              and '.'. -->
diff --git a/java/res/xml-xlarge/kbd_phone_symbols.xml b/java/res/xml-xlarge/kbd_phone_symbols.xml
index 09eb403..7eadb96 100644
--- a/java/res/xml-xlarge/kbd_phone_symbols.xml
+++ b/java/res/xml-xlarge/kbd_phone_symbols.xml
@@ -69,7 +69,6 @@
     <Row>
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignLeft"
             latin:keyEdgeFlags="left" />
         <Spacer
             latin:horizontalGap="4.458%p" />
diff --git a/java/res/xml-xlarge/kbd_popup_template.xml b/java/res/xml-xlarge/kbd_popup_template.xml
index 55ebda5..aa99cee 100644
--- a/java/res/xml-xlarge/kbd_popup_template.xml
+++ b/java/res/xml-xlarge/kbd_popup_template.xml
@@ -19,9 +19,9 @@
 -->
 
 <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="7.5%p"
-    latin:horizontalGap="@dimen/key_horizontal_gap"
+    latin:keyWidth="5.0%p"
+    latin:horizontalGap="0px"
     latin:verticalGap="0px"
-    latin:keyHeight="@dimen/key_height"
+    latin:keyHeight="@dimen/popup_key_height"
     >
 </Keyboard>
diff --git a/java/res/xml-xlarge/kbd_symbols.xml b/java/res/xml-xlarge/kbd_symbols.xml
index 7197115..85deb87 100644
--- a/java/res/xml-xlarge/kbd_symbols.xml
+++ b/java/res/xml-xlarge/kbd_symbols.xml
@@ -124,7 +124,6 @@
     >
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignLeft"
             latin:keyWidth="15.192%p"
             latin:keyEdgeFlags="left" />
         <Key
@@ -155,7 +154,6 @@
             latin:popupCharacters="¿" />
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignRight"
             latin:keyWidth="12.530%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml-xlarge/kbd_symbols_shift.xml b/java/res/xml-xlarge/kbd_symbols_shift.xml
index 4742967..5620e1d 100644
--- a/java/res/xml-xlarge/kbd_symbols_shift.xml
+++ b/java/res/xml-xlarge/kbd_symbols_shift.xml
@@ -104,7 +104,6 @@
     >
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignLeft"
             latin:keyWidth="15.192%p"
             latin:keyEdgeFlags="left" />
         <Key
@@ -131,7 +130,6 @@
             latin:keyLabel="¿" />
         <Key
             latin:keyStyle="moreKeyStyle"
-            latin:keyLabelOption="alignRight"
             latin:keyWidth="12.530%p"
             latin:keyEdgeFlags="right" />
     </Row>
diff --git a/java/res/xml-xlarge/popup_domains.xml b/java/res/xml-xlarge/popup_domains.xml
index d20bcb1..be0c918 100644
--- a/java/res/xml-xlarge/popup_domains.xml
+++ b/java/res/xml-xlarge/popup_domains.xml
@@ -20,7 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="15%p"
+    latin:keyWidth="5.5%p"
     latin:horizontalGap="0px"
     latin:verticalGap="0px"
     latin:keyHeight="@dimen/popup_key_height"
diff --git a/java/res/xml-xlarge/popup_smileys.xml b/java/res/xml-xlarge/popup_smileys.xml
index 2cfcf74..bdd6805 100644
--- a/java/res/xml-xlarge/popup_smileys.xml
+++ b/java/res/xml-xlarge/popup_smileys.xml
@@ -20,7 +20,7 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyWidth="7.5%p"
+    latin:keyWidth="5.0%p"
     latin:horizontalGap="0px"
     latin:verticalGap="0px"
     latin:keyHeight="@dimen/popup_key_height"
diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboard.java b/java/src/com/android/inputmethod/latin/BaseKeyboard.java
index 00ed453..e2331f3 100644
--- a/java/src/com/android/inputmethod/latin/BaseKeyboard.java
+++ b/java/src/com/android/inputmethod/latin/BaseKeyboard.java
@@ -537,7 +537,8 @@
                 column = 0;
             }
             final Key key = new Key(row);
-            key.x = x;
+            // Horizontal gap is divided equally to both sides of the key.
+            key.x = x + key.gap / 2;
             key.y = y;
             key.label = String.valueOf(c);
             key.codes = new int[] { c };
diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java b/java/src/com/android/inputmethod/latin/BaseKeyboardView.java
index 954f264..3193cd4 100644
--- a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/BaseKeyboardView.java
@@ -170,9 +170,10 @@
     private static final int HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL = -1;
 
     // XML attribute
-    private int mKeyTextSize;
+    private int mKeyLetterSize;
     private int mKeyTextColor;
-    private Typeface mKeyTextStyle = Typeface.DEFAULT;
+    private int mKeyTextColorDisabled;
+    private Typeface mKeyLetterStyle = Typeface.DEFAULT;
     private int mLabelTextSize;
     private int mColorScheme = COLOR_SCHEME_WHITE;
     private int mShadowColor;
@@ -455,12 +456,15 @@
             case R.styleable.BaseKeyboardView_keyPreviewHeight:
                 mPreviewHeight = a.getDimensionPixelSize(attr, 80);
                 break;
-            case R.styleable.BaseKeyboardView_keyTextSize:
-                mKeyTextSize = a.getDimensionPixelSize(attr, 18);
+            case R.styleable.BaseKeyboardView_keyLetterSize:
+                mKeyLetterSize = a.getDimensionPixelSize(attr, 18);
                 break;
             case R.styleable.BaseKeyboardView_keyTextColor:
                 mKeyTextColor = a.getColor(attr, 0xFF000000);
                 break;
+            case R.styleable.BaseKeyboardView_keyTextColorDisabled:
+                mKeyTextColorDisabled = a.getColor(attr, 0xFF000000);
+                break;
             case R.styleable.BaseKeyboardView_labelTextSize:
                 mLabelTextSize = a.getDimensionPixelSize(attr, 14);
                 break;
@@ -477,20 +481,8 @@
             case R.styleable.BaseKeyboardView_backgroundDimAmount:
                 mBackgroundDimAmount = a.getFloat(attr, 0.5f);
                 break;
-            //case android.R.styleable.
-            case R.styleable.BaseKeyboardView_keyTextStyle:
-                int textStyle = a.getInt(attr, 0);
-                switch (textStyle) {
-                    case 0:
-                        mKeyTextStyle = Typeface.DEFAULT;
-                        break;
-                    case 1:
-                        mKeyTextStyle = Typeface.DEFAULT_BOLD;
-                        break;
-                    default:
-                        mKeyTextStyle = Typeface.defaultFromStyle(textStyle);
-                        break;
-                }
+            case R.styleable.BaseKeyboardView_keyLetterStyle:
+                mKeyLetterStyle = Typeface.defaultFromStyle(a.getInt(attr, Typeface.NORMAL));
                 break;
             case R.styleable.BaseKeyboardView_colorScheme:
                 mColorScheme = a.getInt(attr, COLOR_SCHEME_WHITE);
@@ -787,7 +779,6 @@
         final boolean isManualTemporaryUpperCase = (mKeyboard instanceof LatinKeyboard
                 && ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase());
 
-        paint.setColor(mKeyTextColor);
         boolean drawSingleKey = false;
         if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
             // TODO we should use Rect.inset and Rect.contains here.
@@ -820,7 +811,6 @@
             keyBackground.draw(canvas);
 
             final int rowHeight = padding.top + key.height;
-            boolean drawHintIcon = true;
             // Draw key label
             if (label != null) {
                 // For characters, use large font. For labels like "Done", use small font.
@@ -858,6 +848,11 @@
                     if (DEBUG_SHOW_ALIGN && label.length() > 1)
                         drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
                 }
+                if (key.manualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
+                    paint.setColor(mKeyTextColorDisabled);
+                } else {
+                    paint.setColor(mKeyTextColor);
+                }
                 // Set a drop shadow for the text
                 paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor);
                 canvas.drawText(label, positionX, baseline, paint);
@@ -892,7 +887,7 @@
                     drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
                             0x80c00000, new Paint());
             }
-            if (key.hintIcon != null && drawHintIcon) {
+            if (key.hintIcon != null) {
                 final int drawableWidth = key.width;
                 final int drawableHeight = key.height;
                 final int drawableX = 0;
@@ -954,18 +949,20 @@
     private int getLabelSizeAndSetPaint(CharSequence label, Key key, Paint paint) {
         // For characters, use large font. For labels like "Done", use small font.
         final int labelSize;
+        final Typeface labelStyle;
         if (label.length() > 1 && key.codes.length < 2) {
             labelSize = mLabelTextSize;
             if ((key.labelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) {
-                paint.setTypeface(Typeface.DEFAULT);
+                labelStyle = Typeface.DEFAULT;
             } else {
-                paint.setTypeface(Typeface.DEFAULT_BOLD);
+                labelStyle = Typeface.DEFAULT_BOLD;
             }
         } else {
-            labelSize = mKeyTextSize;
-            paint.setTypeface(mKeyTextStyle);
+            labelSize = mKeyLetterSize;
+            labelStyle = mKeyLetterStyle;
         }
         paint.setTextSize(labelSize);
+        paint.setTypeface(labelStyle);
         return labelSize;
     }
 
@@ -1061,11 +1058,11 @@
             mPreviewText.setCompoundDrawables(null, null, null, null);
             mPreviewText.setText(adjustCase(tracker.getPreviewText(key)));
             if (key.label.length() > 1 && key.codes.length < 2) {
-                mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize);
+                mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
                 mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
             } else {
                 mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
-                mPreviewText.setTypeface(mKeyTextStyle);
+                mPreviewText.setTypeface(mKeyLetterStyle);
             }
         } else {
             mPreviewText.setCompoundDrawables(null, null, null,
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 4e02f84..95c7738 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -45,7 +45,6 @@
     private static final int MAX_BIGRAMS = 60;
 
     private static final int TYPED_LETTER_MULTIPLIER = 2;
-    private static final boolean ENABLE_MISSED_CHARACTERS = true;
 
     private int mDicTypeId;
     private int mNativeDict;
@@ -199,27 +198,11 @@
         Arrays.fill(mOutputChars, (char) 0);
         Arrays.fill(mFrequencies, 0);
 
-        int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
-                mOutputChars, mFrequencies,
-                MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1,
+        int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize, mOutputChars,
+                mFrequencies, MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1,
                 nextLettersFrequencies,
                 nextLettersFrequencies != null ? nextLettersFrequencies.length : 0);
 
-        // If there aren't sufficient suggestions, search for words by allowing wild cards at
-        // the different character positions. This feature is not ready for prime-time as we need
-        // to figure out the best ranking for such words compared to proximity corrections and
-        // completions.
-        if (ENABLE_MISSED_CHARACTERS && count < 5) {
-            for (int skip = 0; skip < codesSize; skip++) {
-                int tempCount = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
-                        mOutputChars, mFrequencies,
-                        MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip,
-                        null, 0);
-                count = Math.max(count, tempCount);
-                if (tempCount > 0) break;
-            }
-        }
-
         for (int j = 0; j < count; j++) {
             if (mFrequencies[j] < 1) break;
             int start = j * MAX_WORD_LENGTH;
diff --git a/java/src/com/android/inputmethod/latin/LatinIMESettings.java b/java/src/com/android/inputmethod/latin/LatinIMESettings.java
index 669192f..ae66461 100644
--- a/java/src/com/android/inputmethod/latin/LatinIMESettings.java
+++ b/java/src/com/android/inputmethod/latin/LatinIMESettings.java
@@ -32,7 +32,10 @@
 import android.preference.PreferenceGroup;
 import android.speech.SpeechRecognizer;
 import android.text.AutoText;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
 import android.util.Log;
+import android.widget.TextView;
 
 import java.util.Locale;
 
@@ -60,6 +63,8 @@
     private CheckBoxPreference mBigramSuggestion;
     private boolean mVoiceOn;
 
+    private AlertDialog mDialog;
+
     private VoiceInputLogger mLogger;
 
     private boolean mOkClicked = false;
@@ -91,8 +96,15 @@
 
         final boolean showSettingsKeyOption = getResources().getBoolean(
                 R.bool.config_enable_show_settings_key_option);
-        if (!showSettingsKeyOption)
+        if (!showSettingsKeyOption) {
             getPreferenceScreen().removePreference(mSettingsKeyPreference);
+        }
+
+        final boolean showVoiceKeyOption = getResources().getBoolean(
+                R.bool.config_enable_show_voice_key_option);
+        if (!showVoiceKeyOption) {
+            getPreferenceScreen().removePreference(mVoicePreference);
+        }
 
         Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
         if (vibrator == null || !vibrator.hasVibrator()) {
@@ -149,6 +161,13 @@
     private void showVoiceConfirmation() {
         mOkClicked = false;
         showDialog(VOICE_INPUT_CONFIRM_DIALOG);
+        // Make URL in the dialog message clickable
+        if (mDialog != null) {
+            TextView textView = (TextView) mDialog.findViewById(android.R.id.message);
+            if (textView != null) {
+                textView.setMovementMethod(LinkMovementMethod.getInstance());
+            }
+        }
     }
 
     private void updateVoiceModeSummary() {
@@ -184,18 +203,20 @@
                 boolean localeSupported = SubtypeSwitcher.getInstance().isVoiceSupported(
                         Locale.getDefault().toString());
 
+                final CharSequence message;
                 if (localeSupported) {
-                    String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" +
-                            getString(R.string.voice_hint_dialog_message);
-                    builder.setMessage(message);
+                    message = TextUtils.concat(
+                            getText(R.string.voice_warning_may_not_understand), "\n\n",
+                                    getText(R.string.voice_hint_dialog_message));
                 } else {
-                    String message = getString(R.string.voice_warning_locale_not_supported) +
-                            "\n\n" + getString(R.string.voice_warning_may_not_understand) + "\n\n" +
-                            getString(R.string.voice_hint_dialog_message);
-                    builder.setMessage(message);
+                    message = TextUtils.concat(
+                            getText(R.string.voice_warning_locale_not_supported), "\n\n",
+                                    getText(R.string.voice_warning_may_not_understand), "\n\n",
+                                            getText(R.string.voice_hint_dialog_message));
                 }
-
+                builder.setMessage(message);
                 AlertDialog dialog = builder.create();
+                mDialog = dialog;
                 dialog.setOnDismissListener(this);
                 mLogger.settingsWarningDialogShown();
                 return dialog;
diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
index fd9559d..5574a21 100644
--- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
+++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
@@ -27,11 +27,23 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.content.SharedPreferences;
+import android.net.Uri;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
+import android.provider.Browser;
 import android.speech.SpeechRecognizer;
+import android.text.Layout;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.method.MovementMethod;
+import android.text.style.ClickableSpan;
+import android.text.style.URLSpan;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
@@ -41,6 +53,7 @@
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.TextView;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -173,7 +186,7 @@
                 switchToLastInputMethod();
             }
         });
-        // When the dialog is dismissed by user's cancellation, swith back to the last input method.
+        // When the dialog is dismissed by user's cancellation, switch back to the last input method
         builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
             @Override
             public void onCancel(DialogInterface arg0) {
@@ -182,16 +195,18 @@
             }
         });
 
+        final CharSequence message;
         if (mLocaleSupportedForVoiceInput) {
-            String message = mContext.getString(R.string.voice_warning_may_not_understand)
-                    + "\n\n" + mContext.getString(R.string.voice_warning_how_to_turn_off);
-            builder.setMessage(message);
+            message = TextUtils.concat(
+                    mContext.getText(R.string.voice_warning_may_not_understand), "\n\n",
+                            mContext.getText(R.string.voice_warning_how_to_turn_off));
         } else {
-            String message = mContext.getString(R.string.voice_warning_locale_not_supported)
-                    + "\n\n" + mContext.getString(R.string.voice_warning_may_not_understand)
-                    + "\n\n" + mContext.getString(R.string.voice_warning_how_to_turn_off);
-            builder.setMessage(message);
+            message = TextUtils.concat(
+                    mContext.getText(R.string.voice_warning_locale_not_supported), "\n\n",
+                            mContext.getText(R.string.voice_warning_may_not_understand), "\n\n",
+                                    mContext.getText(R.string.voice_warning_how_to_turn_off));
         }
+        builder.setMessage(message);
 
         builder.setTitle(R.string.voice_warning_title);
         mVoiceWarningDialog = builder.create();
@@ -203,6 +218,79 @@
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
         mVoiceInput.logKeyboardWarningDialogShown();
         mVoiceWarningDialog.show();
+        // Make URL in the dialog message clickable
+        TextView textView = (TextView) mVoiceWarningDialog.findViewById(android.R.id.message);
+        if (textView != null) {
+            final CustomLinkMovementMethod method = CustomLinkMovementMethod.getInstance();
+            method.setVoiceWarningDialog(mVoiceWarningDialog);
+            textView.setMovementMethod(method);
+        }
+    }
+
+    private static class CustomLinkMovementMethod extends LinkMovementMethod {
+        private static CustomLinkMovementMethod sInstance = new CustomLinkMovementMethod();
+        private AlertDialog mAlertDialog;
+
+        public void setVoiceWarningDialog(AlertDialog alertDialog) {
+            mAlertDialog = alertDialog;
+        }
+
+        public static CustomLinkMovementMethod getInstance() {
+            return sInstance;
+        }
+
+        // Almost the same as LinkMovementMethod.onTouchEvent(), but overrides it for
+        // FLAG_ACTIVITY_NEW_TASK and mAlertDialog.cancel().
+        @Override
+        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
+            int action = event.getAction();
+
+            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
+                int x = (int) event.getX();
+                int y = (int) event.getY();
+
+                x -= widget.getTotalPaddingLeft();
+                y -= widget.getTotalPaddingTop();
+
+                x += widget.getScrollX();
+                y += widget.getScrollY();
+
+                Layout layout = widget.getLayout();
+                int line = layout.getLineForVertical(y);
+                int off = layout.getOffsetForHorizontal(line, x);
+
+                ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
+
+                if (link.length != 0) {
+                    if (action == MotionEvent.ACTION_UP) {
+                        if (link[0] instanceof URLSpan) {
+                            URLSpan urlSpan = (URLSpan) link[0];
+                            Uri uri = Uri.parse(urlSpan.getURL());
+                            Context context = widget.getContext();
+                            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
+                            if (mAlertDialog != null) {
+                                // Go back to the previous IME for now.
+                                // TODO: If we can find a way to bring the new activity to front
+                                // while keeping the warning dialog, we don't need to cancel here.
+                                mAlertDialog.cancel();
+                            }
+                            context.startActivity(intent);
+                        } else {
+                            link[0].onClick(widget);
+                        }
+                    } else if (action == MotionEvent.ACTION_DOWN) {
+                        Selection.setSelection(buffer, buffer.getSpanStart(link[0]),
+                                buffer.getSpanEnd(link[0]));
+                    }
+                    return true;
+                } else {
+                    Selection.removeSelection(buffer);
+                }
+            }
+            return super.onTouchEvent(widget, buffer, event);
+        }
     }
 
     public void showPunctuationHintIfNecessary() {
diff --git a/native/Android.mk b/native/Android.mk
index b294469..97051c9 100644
--- a/native/Android.mk
+++ b/native/Android.mk
@@ -8,11 +8,22 @@
 	src/dictionary.cpp \
 	src/char_utils.cpp
 
-LOCAL_NDK_VERSION := 4
+#FLAG_DBG := true
+
+ifneq ($(FLAG_DBG), true)
+    LOCAL_NDK_VERSION := 4
+endif
+
 LOCAL_SDK_VERSION := 8
 
 LOCAL_MODULE := libjni_latinime
 
 LOCAL_MODULE_TAGS := user
 
+ifeq ($(FLAG_DBG), true)
+    $(warning "Making debug build.")
+    LOCAL_CFLAGS += -DFLAG_DBG
+    LOCAL_SHARED_LIBRARIES := libcutils libutils
+endif
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/native/src/dictionary.cpp b/native/src/dictionary.cpp
index 1a39f585b4..b20dc11 100644
--- a/native/src/dictionary.cpp
+++ b/native/src/dictionary.cpp
@@ -19,23 +19,33 @@
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <string.h>
-//#define LOG_TAG "dictionary.cpp"
-//#include <cutils/log.h>
+
+#ifdef FLAG_DBG
+#define LOG_TAG "LatinIME: dictionary.cpp"
+#include <cutils/log.h>
+#define DEBUG_DICT 1
+#else // FLAG_DBG
 #define LOGI
+#define DEBUG_DICT 0
+#endif // FLAG_DBG
 
 #include "dictionary.h"
 #include "basechars.h"
 #include "char_utils.h"
 
-#define DEBUG_DICT 0
 #define DICTIONARY_VERSION_MIN 200
 #define DICTIONARY_HEADER_SIZE 2
 #define NOT_VALID_WORD -99
 
+#define SUGGEST_MISSING_CHARACTERS true
+#define SUGGEST_MISSING_CHARACTERS_THRESHOLD 5
+
+
 namespace latinime {
 
 Dictionary::Dictionary(void *dict, int typedLetterMultiplier, int fullWordMultiplier)
 {
+    LOGI("Dictionary - constructor");
     mDict = (unsigned char*) dict;
     mTypedLetterMultiplier = typedLetterMultiplier;
     mFullWordMultiplier = fullWordMultiplier;
@@ -50,7 +60,42 @@
         int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
         int *nextLetters, int nextLettersSize)
 {
-    int suggWords;
+
+    initSuggestions(codes, codesSize, outWords, frequencies, maxWordLength, maxWords,
+            maxAlternatives);
+
+    int suggestedWordsCount = getSuggestionCandidates(codesSize, maxWords, skipPos, nextLetters,
+            nextLettersSize);
+
+    // If there aren't sufficient suggestions, search for words by allowing wild cards at
+    // the different character positions. This feature is not ready for prime-time as we need
+    // to figure out the best ranking for such words compared to proximity corrections and
+    // completions.
+    if (SUGGEST_MISSING_CHARACTERS && suggestedWordsCount < SUGGEST_MISSING_CHARACTERS_THRESHOLD) {
+        for (int i = 0; i < codesSize; ++i) {
+            int tempCount = getSuggestionCandidates(codesSize, maxWords, i, NULL, 0);
+            if (tempCount > suggestedWordsCount) {
+                suggestedWordsCount = tempCount;
+                break;
+            }
+        }
+    }
+
+    if (DEBUG_DICT) {
+        LOGI("Returning %d words", suggestedWordsCount);
+        LOGI("Next letters: ");
+        for (int k = 0; k < nextLettersSize; k++) {
+            if (nextLetters[k] > 0) {
+                LOGI("%c = %d,", k, nextLetters[k]);
+            }
+        }
+        LOGI("\n");
+    }
+    return suggestedWordsCount;
+}
+
+void Dictionary::initSuggestions(int *codes, int codesSize, unsigned short *outWords,
+        int *frequencies, int maxWordLength, int maxWords, int maxAlternatives) {
     mFrequencies = frequencies;
     mOutputChars = outWords;
     mInputCodes = codes;
@@ -58,39 +103,29 @@
     mMaxAlternatives = maxAlternatives;
     mMaxWordLength = maxWordLength;
     mMaxWords = maxWords;
-    mSkipPos = skipPos;
     mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2;
-    mNextLettersFrequencies = nextLetters;
-    mNextLettersSize = nextLettersSize;
+}
 
+int Dictionary::getSuggestionCandidates(int inputLength, int maxWords, int skipPos,
+        int *nextLetters, int nextLettersSize) {
     if (checkIfDictVersionIsLatest()) {
-        getWordsRec(DICTIONARY_HEADER_SIZE, 0, mInputLength * 3, false, 1, 0, 0);
+        getWordsRec(DICTIONARY_HEADER_SIZE, 0, inputLength * 3, false, 1, 0, 0, skipPos,
+                nextLetters, nextLettersSize);
     } else {
-        getWordsRec(0, 0, mInputLength * 3, false, 1, 0, 0);
+        getWordsRec(0, 0, inputLength * 3, false, 1, 0, 0, skipPos, nextLetters, nextLettersSize);
     }
 
     // Get the word count
-    suggWords = 0;
-    while (suggWords < mMaxWords && mFrequencies[suggWords] > 0) suggWords++;
-    if (DEBUG_DICT) LOGI("Returning %d words", suggWords);
-
-    if (DEBUG_DICT) {
-        LOGI("Next letters: ");
-        for (int k = 0; k < nextLettersSize; k++) {
-            if (mNextLettersFrequencies[k] > 0) {
-                LOGI("%c = %d,", k, mNextLettersFrequencies[k]);
-            }
-        }
-        LOGI("\n");
+    int suggestedWordsCount = 0;
+    while (suggestedWordsCount < maxWords && mFrequencies[suggestedWordsCount] > 0) {
+        suggestedWordsCount++;
     }
-    return suggWords;
+    return suggestedWordsCount;
 }
 
-void
-Dictionary::registerNextLetter(unsigned short c)
-{
-    if (c < mNextLettersSize) {
-        mNextLettersFrequencies[c]++;
+void Dictionary::registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize) {
+    if (c < nextLettersSize) {
+        nextLetters[c]++;
     }
 }
 
@@ -281,7 +316,7 @@
 
 void
 Dictionary::getWordsRec(int pos, int depth, int maxDepth, bool completion, int snr, int inputIndex,
-                        int diffs)
+                        int diffs, int skipPos, int *nextLetters, int nextLettersSize)
 {
     // Optimization: Prune out words that are too long compared to how much was typed.
     if (depth > maxDepth) {
@@ -315,19 +350,20 @@
             mWord[depth] = c;
             if (terminal) {
                 addWord(mWord, depth + 1, freq * snr);
-                if (depth >= mInputLength && mSkipPos < 0) {
-                    registerNextLetter(mWord[mInputLength]);
+                if (depth >= mInputLength && skipPos < 0) {
+                    registerNextLetter(mWord[mInputLength], nextLetters, nextLettersSize);
                 }
             }
             if (childrenAddress != 0) {
-                getWordsRec(childrenAddress, depth + 1, maxDepth,
-                            completion, snr, inputIndex, diffs);
+                getWordsRec(childrenAddress, depth + 1, maxDepth, completion, snr, inputIndex,
+                        diffs, skipPos, nextLetters, nextLettersSize);
             }
-        } else if ((c == QUOTE && currentChars[0] != QUOTE) || mSkipPos == depth) {
+        } else if ((c == QUOTE && currentChars[0] != QUOTE) || skipPos == depth) {
             // Skip the ' or other letter and continue deeper
             mWord[depth] = c;
             if (childrenAddress != 0) {
-                getWordsRec(childrenAddress, depth + 1, maxDepth, false, snr, inputIndex, diffs);
+                getWordsRec(childrenAddress, depth + 1, maxDepth, false, snr, inputIndex, diffs,
+                        skipPos, nextLetters, nextLettersSize);
             }
         } else {
             int j = 0;
@@ -340,22 +376,23 @@
                             if (//INCLUDE_TYPED_WORD_IF_VALID ||
                                 !sameAsTyped(mWord, depth + 1)) {
                                 int finalFreq = freq * snr * addedWeight;
-                                if (mSkipPos < 0) finalFreq *= mFullWordMultiplier;
+                                if (skipPos < 0) finalFreq *= mFullWordMultiplier;
                                 addWord(mWord, depth + 1, finalFreq);
                             }
                         }
                         if (childrenAddress != 0) {
                             getWordsRec(childrenAddress, depth + 1,
                                     maxDepth, true, snr * addedWeight, inputIndex + 1,
-                                    diffs + (j > 0));
+                                    diffs + (j > 0), skipPos, nextLetters, nextLettersSize);
                         }
                     } else if (childrenAddress != 0) {
                         getWordsRec(childrenAddress, depth + 1, maxDepth,
-                                false, snr * addedWeight, inputIndex + 1, diffs + (j > 0));
+                                false, snr * addedWeight, inputIndex + 1, diffs + (j > 0),
+                                skipPos, nextLetters, nextLettersSize);
                     }
                 }
                 j++;
-                if (mSkipPos >= 0) break;
+                if (skipPos >= 0) break;
             }
         }
     }
diff --git a/native/src/dictionary.h b/native/src/dictionary.h
index d13496e..2dac3b2 100644
--- a/native/src/dictionary.h
+++ b/native/src/dictionary.h
@@ -48,7 +48,10 @@
     ~Dictionary();
 
 private:
-
+    void initSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
+            int maxWordLength, int maxWords, int maxAlternatives);
+    int getSuggestionCandidates(int inputLength, int maxWords, int skipPos, int *nextLetters,
+            int nextLettersSize);
     void getVersionNumber();
     bool checkIfDictVersionIsLatest();
     int getAddress(int *pos);
@@ -70,9 +73,9 @@
     bool addWordBigram(unsigned short *word, int length, int frequency);
     unsigned short toLowerCase(unsigned short c);
     void getWordsRec(int pos, int depth, int maxDepth, bool completion, int frequency,
-            int inputIndex, int diffs);
+            int inputIndex, int diffs, int skipPos, int *nextLetters, int nextLettersSize);
     int isValidWordRec(int pos, unsigned short *word, int offset, int length);
-    void registerNextLetter(unsigned short c);
+    void registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize);
 
     unsigned char *mDict;
     void *mAsset;
@@ -88,13 +91,10 @@
     int mInputLength;
     int mMaxAlternatives;
     unsigned short mWord[128];
-    int mSkipPos;
     int mMaxEditDistance;
 
     int mFullWordMultiplier;
     int mTypedLetterMultiplier;
-    int *mNextLettersFrequencies;
-    int mNextLettersSize;
     int mVersion;
     int mBigram;
 };