diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index f55e9bf..5cd995b 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -35,7 +35,7 @@
     <!-- Label for "switch to more symbol" modifier key.  Must be short to fit on key! -->
     <string name="label_to_more_symbol_key">= \\ &lt;</string>
     <!-- Label for "switch to more symbol" modifier key on tablets.  Must be short to fit on key! -->
-    <string name="label_to_more_symbol_for_tablet_key">\\ ^ [ {</string>
+    <string name="label_to_more_symbol_for_tablet_key">~ \\ {</string>
 
     <!-- Label for "Tab" key.  Must be short to fit on key! -->
     <string name="label_tab_key">Tab</string>
diff --git a/java/res/values/sudden-jumping-touch-event-device-list.xml b/java/res/values/sudden-jumping-touch-event-device-list.xml
new file mode 100644
index 0000000..275a262
--- /dev/null
+++ b/java/res/values/sudden-jumping-touch-event-device-list.xml
@@ -0,0 +1,27 @@
+<?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>
+    <string-array name="sudden_jumping_touch_event_device_list">
+        <!-- Nexus One -->
+        <item>passion</item>
+        <!-- Droid -->
+        <item>sholes</item>
+    </string-array>
+</resources>
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index 15a3d1d..b93d300 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -118,19 +118,4 @@
         latin:keyLabelOption="fontNormal|hasPopupHint"
         latin:keyOutputText="@string/keylabel_for_popular_domain"
         latin:popupCharacters="@string/alternates_for_popular_domain" />
-    <switch>
-        <case
-            latin:passwordInput="true"
-        >
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="false" />
-        </case>
-        <!-- latin:passwordInput="false" -->
-        <default>
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="true" />
-        </default>
-    </switch>
 </merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml b/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml
index 2909acb..c5143d9 100644
--- a/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml
+++ b/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml
@@ -33,28 +33,21 @@
         <Key
             latin:keyLabel="|" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="•"
             latin:popupCharacters="♪,♥,♠,♦,♣" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="√" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="π"
             latin:popupCharacters="Π" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="÷" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="×" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="§"
             latin:popupCharacters="¶" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="Δ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
@@ -65,27 +58,21 @@
         latin:keyWidth="9.0%p"
     >
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="£"
             latin:keyXPos="4.5%p" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¢" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="€" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¥" />
         <Key
             latin:keyLabel="^"
             latin:popupCharacters="↑,↓,←,→" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="°"
             latin:popupCharacters="′,″" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="±"
             latin:popupCharacters="∞" />
         <Key
@@ -106,26 +93,20 @@
         <Key
             latin:keyLabel="\\" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="©" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="®" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="™" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="℅" />
         <Key
             latin:keyLabel="[" />
         <Key
             latin:keyLabel="]" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¡" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¿" />
     </Row>
     <Row
diff --git a/java/res/xml-sw768dp/kbd_key_styles.xml b/java/res/xml-sw768dp/kbd_key_styles.xml
index 1711c42..7c74bb5 100644
--- a/java/res/xml-sw768dp/kbd_key_styles.xml
+++ b/java/res/xml-sw768dp/kbd_key_styles.xml
@@ -104,19 +104,4 @@
         latin:keyLabelOption="fontNormal|hasPopupHint"
         latin:keyOutputText="@string/keylabel_for_popular_domain"
         latin:popupCharacters="@string/alternates_for_popular_domain" />
-    <switch>
-        <case
-            latin:passwordInput="true"
-        >
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="false" />
-        </case>
-        <!-- latin:passwordInput="false" -->
-        <default>
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="true" />
-        </default>
-    </switch>
 </merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml b/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
index 1f43a0f..82bc4b2 100644
--- a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
+++ b/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
@@ -37,28 +37,21 @@
         <Key
             latin:keyLabel="|" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="•"
             latin:popupCharacters="♪,♥,♠,♦,♣" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="√" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="π"
             latin:popupCharacters="Π" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="÷" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="×" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="§"
             latin:popupCharacters="¶" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="Δ" />
         <Key
             latin:keyStyle="deleteKeyStyle"
@@ -73,26 +66,20 @@
             latin:keyLabelOption="alignLeft"
             latin:keyWidth="11.172%p" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="£" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¢" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="€" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¥" />
         <Key
             latin:keyLabel="^"
             latin:popupCharacters="↑,↓,←,→" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="°"
             latin:popupCharacters="′,″" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="±"
             latin:popupCharacters="∞" />
         <Key
@@ -113,26 +100,20 @@
         <Key
             latin:keyLabel="\\" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="©" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="®" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="™" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="℅" />
         <Key
             latin:keyLabel="[" />
         <Key
             latin:keyLabel="]" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¡" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¿" />
         <Key
             latin:keyStyle="backFromMoreSymbolKeyStyle"
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index 5612251..4846898 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -215,29 +215,6 @@
         latin:code="@integer/key_shift"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:parentStyle="functionalKeyStyle" />
-    <switch>
-        <case
-            latin:passwordInput="true"
-        >
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="false" />
-            <key-style
-                latin:styleName="nonPasswordFunctionalKeyStyle"
-                latin:enabled="false"
-                latin:parentStyle="functionalKeyStyle" />
-        </case>
-        <!-- latin:passwordInput="false" -->
-        <default>
-            <key-style
-                latin:styleName="nonPasswordSymbolKeyStyle"
-                latin:enabled="true" />
-            <key-style
-                latin:styleName="nonPasswordFunctionalKeyStyle"
-                latin:enabled="true"
-                latin:parentStyle="functionalKeyStyle" />
-        </default>
-    </switch>
     <key-style
         latin:styleName="punctuationKeyStyle"
         latin:keyLabel="."
diff --git a/java/res/xml/kbd_rows_symbols_shift.xml b/java/res/xml/kbd_rows_symbols_shift.xml
index d523415..ff272f1 100644
--- a/java/res/xml/kbd_rows_symbols_shift.xml
+++ b/java/res/xml/kbd_rows_symbols_shift.xml
@@ -33,21 +33,16 @@
         <Key
             latin:keyLabel="|" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="•"
             latin:popupCharacters="♪,♥,♠,♦,♣" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="√" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="π"
             latin:popupCharacters="Π" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="÷" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="×" />
         <Key
             latin:keyLabel="{" />
@@ -61,16 +56,12 @@
         <Key
             latin:keyStyle="nonSpecialBackgroundTabKeyStyle" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="£" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¢" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="€" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="°"
             latin:popupCharacters="′,″" />
         <Key
@@ -95,16 +86,12 @@
             latin:keyWidth="15%p"
             latin:visualInsetsRight="1%p" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="™" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="®" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="©" />
         <Key
-            latin:keyStyle="nonPasswordSymbolKeyStyle"
             latin:keyLabel="¶"
             latin:popupCharacters="§" />
         <Key
diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml
index 9cb453f..bcab19b 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/kbd_symbols_shift_row4.xml
@@ -35,13 +35,13 @@
                 <Key
                     latin:keyLabel="„"
                     latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
-                    latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+                    latin:keyStyle="functionalKeyStyle" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="50%p" />
                 <Key
                     latin:keyLabel="…"
-                    latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+                    latin:keyStyle="functionalKeyStyle" />
                 <Key
                     latin:keyStyle="returnKeyStyle"
                     latin:keyWidth="fillRight" />
@@ -57,14 +57,14 @@
                     latin:keyLabel="„"
                     latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
                     latin:keyWidth="9.2%p"
-                    latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+                    latin:keyStyle="functionalKeyStyle" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
                     latin:keyWidth="35.83%p" />
                 <Key
                     latin:keyLabel="…"
                     latin:keyWidth="9.2%p"
-                    latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+                    latin:keyStyle="functionalKeyStyle" />
                 <Key
                     latin:keyStyle="returnKeyStyle"
                     latin:keyWidth="fillRight" />
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index 3dca9aa..8185619 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -35,7 +35,7 @@
 import com.android.inputmethod.compat.MotionEventCompatUtils;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.KeyDetector;
-import com.android.inputmethod.keyboard.LatinKeyboardBaseView;
+import com.android.inputmethod.keyboard.LatinKeyboardView;
 import com.android.inputmethod.keyboard.PointerTracker;
 
 public class AccessibleKeyboardViewProxy {
@@ -47,7 +47,7 @@
 
     private InputMethodService mInputMethod;
     private FlickGestureDetector mGestureDetector;
-    private LatinKeyboardBaseView mView;
+    private LatinKeyboardView mView;
     private AccessibleKeyboardActionListener mListener;
     private AudioManagerCompatWrapper mAudioManager;
 
@@ -65,7 +65,7 @@
         return sInstance;
     }
 
-    public static void setView(LatinKeyboardBaseView view) {
+    public static void setView(LatinKeyboardView view) {
         sInstance.mView = view;
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 397b7b1..f56b523 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -295,12 +295,8 @@
             mY = y;
             mWidth = keyWidth - mHorizontalGap;
 
-            CharSequence[] popupCharacters = style.getTextArray(
+            final CharSequence[] popupCharacters = style.getTextArray(
                     keyAttr, R.styleable.Keyboard_Key_popupCharacters);
-            if (params.mId.mPasswordInput) {
-                popupCharacters = PopupCharactersParser.filterOut(
-                        res, popupCharacters, PopupCharactersParser.NON_ASCII_FILTER);
-            }
             // In Arabic symbol layouts, we'd like to keep digits in popup characters regardless of
             // config_digit_popup_characters_enabled.
             if (params.mId.isAlphabetKeyboard() && !res.getBoolean(
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 0a3acb4..3298c41 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -91,6 +91,10 @@
         mProximityThresholdSquare = threshold * threshold;
     }
 
+    public boolean alwaysAllowsSlidingInput() {
+        return false;
+    }
+
     /**
      * Computes maximum size of the array that can contain all nearby key indices returned by
      * {@link #getKeyIndexAndNearbyCodes}.
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 3b3e1f8..1b6f57b 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -141,7 +141,7 @@
         }
     }
 
-    public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardBaseView view) {
+    public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
         mSpacebarTextFadeFactor = fadeFactor;
         updateSpacebarForLocale(false);
         if (view != null)
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
deleted file mode 100644
index 4a7b2bd..0000000
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.inputmethod.keyboard;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.PopupWindow;
-
-import com.android.inputmethod.accessibility.AccessibilityUtils;
-import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
-import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
-import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
-import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder;
-import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-import com.android.inputmethod.latin.Utils;
-
-import java.util.WeakHashMap;
-
-/**
- * A view that is responsible for detecting key presses and touch movements.
- *
- * @attr ref R.styleable#KeyboardView_keyHysteresisDistance
- * @attr ref R.styleable#KeyboardView_verticalCorrection
- * @attr ref R.styleable#KeyboardView_popupLayout
- */
-public class LatinKeyboardBaseView extends KeyboardView implements PointerTracker.KeyEventHandler {
-    private static final String TAG = LatinKeyboardBaseView.class.getSimpleName();
-
-    private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
-
-    // Timing constants
-    private final int mKeyRepeatInterval;
-
-    // XML attribute
-    private final float mVerticalCorrection;
-    private final int mPopupLayout;
-
-    // Mini keyboard
-    private PopupWindow mPopupWindow;
-    private PopupPanel mPopupPanel;
-    private int mPopupPanelPointerTrackerId;
-    private final WeakHashMap<Key, PopupPanel> mPopupPanelCache =
-            new WeakHashMap<Key, PopupPanel>();
-
-    /** Listener for {@link KeyboardActionListener}. */
-    private KeyboardActionListener mKeyboardActionListener;
-
-    private final boolean mHasDistinctMultitouch;
-    private int mOldPointerCount = 1;
-    private int mOldKeyIndex;
-
-    protected KeyDetector mKeyDetector;
-
-    // To detect double tap.
-    protected GestureDetector mGestureDetector;
-
-    private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
-
-    private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardBaseView>
-            implements TimerProxy {
-        private static final int MSG_REPEAT_KEY = 1;
-        private static final int MSG_LONGPRESS_KEY = 2;
-        private static final int MSG_IGNORE_DOUBLE_TAP = 3;
-
-        private boolean mInKeyRepeat;
-
-        public KeyTimerHandler(LatinKeyboardBaseView outerInstance) {
-            super(outerInstance);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            final LatinKeyboardBaseView keyboardView = getOuterInstance();
-            final PointerTracker tracker = (PointerTracker) msg.obj;
-            switch (msg.what) {
-            case MSG_REPEAT_KEY:
-                tracker.onRepeatKey(msg.arg1);
-                startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker);
-                break;
-            case MSG_LONGPRESS_KEY:
-                keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker);
-                break;
-            }
-        }
-
-        @Override
-        public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
-            mInKeyRepeat = true;
-            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
-        }
-
-        public void cancelKeyRepeatTimer() {
-            mInKeyRepeat = false;
-            removeMessages(MSG_REPEAT_KEY);
-        }
-
-        public boolean isInKeyRepeat() {
-            return mInKeyRepeat;
-        }
-
-        @Override
-        public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
-            cancelLongPressTimer();
-            sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
-        }
-
-        @Override
-        public void cancelLongPressTimer() {
-            removeMessages(MSG_LONGPRESS_KEY);
-        }
-
-        @Override
-        public void cancelKeyTimers() {
-            cancelKeyRepeatTimer();
-            cancelLongPressTimer();
-            removeMessages(MSG_IGNORE_DOUBLE_TAP);
-        }
-
-        public void startIgnoringDoubleTap() {
-            sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
-                    ViewConfiguration.getDoubleTapTimeout());
-        }
-
-        public boolean isIgnoringDoubleTap() {
-            return hasMessages(MSG_IGNORE_DOUBLE_TAP);
-        }
-
-        public void cancelAllMessages() {
-            cancelKeyTimers();
-        }
-    }
-
-    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
-        private boolean mProcessingShiftDoubleTapEvent = false;
-
-        @Override
-        public boolean onDoubleTap(MotionEvent firstDown) {
-            final Keyboard keyboard = getKeyboard();
-            if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard instanceof LatinKeyboard
-                    && ((LatinKeyboard) keyboard).isAlphaKeyboard()) {
-                final int pointerIndex = firstDown.getActionIndex();
-                final int id = firstDown.getPointerId(pointerIndex);
-                final PointerTracker tracker = getPointerTracker(id);
-                // If the first down event is on shift key.
-                if (tracker.isOnShiftKey((int) firstDown.getX(), (int) firstDown.getY())) {
-                    mProcessingShiftDoubleTapEvent = true;
-                    return true;
-                }
-            }
-            mProcessingShiftDoubleTapEvent = false;
-            return false;
-        }
-
-        @Override
-        public boolean onDoubleTapEvent(MotionEvent secondTap) {
-            if (mProcessingShiftDoubleTapEvent
-                    && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
-                final MotionEvent secondDown = secondTap;
-                final int pointerIndex = secondDown.getActionIndex();
-                final int id = secondDown.getPointerId(pointerIndex);
-                final PointerTracker tracker = getPointerTracker(id);
-                // If the second down event is also on shift key.
-                if (tracker.isOnShiftKey((int) secondDown.getX(), (int) secondDown.getY())) {
-                    // Detected a double tap on shift key. If we are in the ignoring double tap
-                    // mode, it means we have already turned off caps lock in
-                    // {@link KeyboardSwitcher#onReleaseShift} .
-                    final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
-                    if (!ignoringDoubleTap)
-                        onDoubleTapShiftKey(tracker);
-                    return true;
-                }
-                // Otherwise these events should not be handled as double tap.
-                mProcessingShiftDoubleTapEvent = false;
-            }
-            return mProcessingShiftDoubleTapEvent;
-        }
-    }
-
-    public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.keyboardViewStyle);
-    }
-
-    public LatinKeyboardBaseView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        final TypedArray a = context.obtainStyledAttributes(
-                attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
-        mVerticalCorrection = a.getDimensionPixelOffset(
-                R.styleable.KeyboardView_verticalCorrection, 0);
-        mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
-        a.recycle();
-
-        final Resources res = getResources();
-        final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance);
-        mKeyDetector = new KeyDetector(keyHysteresisDistance);
-
-        final boolean ignoreMultitouch = true;
-        mGestureDetector = new GestureDetector(
-                getContext(), new DoubleTapListener(), null, ignoreMultitouch);
-        mGestureDetector.setIsLongpressEnabled(false);
-
-        mHasDistinctMultitouch = context.getPackageManager()
-                .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
-        mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
-
-        PointerTracker.init(mHasDistinctMultitouch, getContext());
-    }
-
-    public void startIgnoringDoubleTap() {
-        if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
-            mKeyTimerHandler.startIgnoringDoubleTap();
-    }
-
-    public void setKeyboardActionListener(KeyboardActionListener listener) {
-        mKeyboardActionListener = listener;
-        PointerTracker.setKeyboardActionListener(listener);
-    }
-
-    /**
-     * Returns the {@link KeyboardActionListener} object.
-     * @return the listener attached to this keyboard
-     */
-    @Override
-    public KeyboardActionListener getKeyboardActionListener() {
-        return mKeyboardActionListener;
-    }
-
-    @Override
-    public KeyDetector getKeyDetector() {
-        return mKeyDetector;
-    }
-
-    @Override
-    public DrawingProxy getDrawingProxy() {
-        return this;
-    }
-
-    @Override
-    public TimerProxy getTimerProxy() {
-        return mKeyTimerHandler;
-    }
-
-    @Override
-    public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
-        final Keyboard keyboard = getKeyboard();
-        if (keyboard instanceof LatinKeyboard) {
-            final LatinKeyboard latinKeyboard = (LatinKeyboard)keyboard;
-            if (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard()) {
-                // Phone and number keyboard never shows popup preview.
-                super.setKeyPreviewPopupEnabled(false, delay);
-                return;
-            }
-        }
-        super.setKeyPreviewPopupEnabled(previewEnabled, delay);
-    }
-
-    /**
-     * Attaches a keyboard to this view. The keyboard can be switched at any time and the
-     * view will re-layout itself to accommodate the keyboard.
-     * @see Keyboard
-     * @see #getKeyboard()
-     * @param keyboard the keyboard to display in this view
-     */
-    @Override
-    public void setKeyboard(Keyboard keyboard) {
-        // Remove any pending messages, except dismissing preview
-        mKeyTimerHandler.cancelKeyTimers();
-        super.setKeyboard(keyboard);
-        mKeyDetector.setKeyboard(
-                keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
-        mKeyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth);
-        PointerTracker.setKeyDetector(mKeyDetector);
-        mPopupPanelCache.clear();
-    }
-
-    /**
-     * Returns whether the device has distinct multi-touch panel.
-     * @return true if the device has distinct multi-touch panel.
-     */
-    public boolean hasDistinctMultitouch() {
-        return mHasDistinctMultitouch;
-    }
-
-    /**
-     * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
-     * codes for adjacent keys.  When disabled, only the primary key code will be
-     * reported.
-     * @param enabled whether or not the proximity correction is enabled
-     */
-    public void setProximityCorrectionEnabled(boolean enabled) {
-        mKeyDetector.setProximityCorrectionEnabled(enabled);
-    }
-
-    /**
-     * Returns true if proximity correction is enabled.
-     */
-    public boolean isProximityCorrectionEnabled() {
-        return mKeyDetector.isProximityCorrectionEnabled();
-    }
-
-    @Override
-    public void cancelAllMessages() {
-        mKeyTimerHandler.cancelAllMessages();
-        super.cancelAllMessages();
-    }
-
-    private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) {
-        // Check if we have a popup layout specified first.
-        if (mPopupLayout == 0) {
-            return false;
-        }
-
-        // Check if we are already displaying popup panel.
-        if (mPopupPanel != null)
-            return false;
-        final Key parentKey = tracker.getKey(keyIndex);
-        if (parentKey == null)
-            return false;
-        return onLongPress(parentKey, tracker);
-    }
-
-    private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
-        // When shift key is double tapped, the first tap is correctly processed as usual tap. And
-        // the second tap is treated as this double tap event, so that we need not mark tracker
-        // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
-        mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
-    }
-
-    // This default implementation returns a popup mini keyboard panel.
-    protected PopupPanel onCreatePopupPanel(Key parentKey) {
-        if (parentKey.mPopupCharacters == null)
-            return null;
-
-        final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null);
-        if (container == null)
-            throw new NullPointerException();
-
-        final PopupMiniKeyboardView miniKeyboardView =
-                (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
-        final Keyboard parentKeyboard = getKeyboard();
-        final Keyboard miniKeyboard = new MiniKeyboardBuilder(
-                this, parentKeyboard.mPopupKeyboardResId, parentKey, parentKeyboard).build();
-        miniKeyboardView.setKeyboard(miniKeyboard);
-
-        container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-
-        return miniKeyboardView;
-    }
-
-    @Override
-    protected boolean needsToDimKeyboard() {
-        return mPopupPanel != null;
-    }
-
-    public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) {
-        final Keyboard keyboard = getKeyboard();
-        // We should not set text fade factor to the keyboard which does not display the language on
-        // its spacebar.
-        if (keyboard instanceof LatinKeyboard && keyboard == oldKeyboard) {
-            ((LatinKeyboard)keyboard).setSpacebarTextFadeFactor(fadeFactor, this);
-        }
-    }
-
-    /**
-     * Called when a key is long pressed. By default this will open mini keyboard associated
-     * with this key.
-     * @param parentKey the key that was long pressed
-     * @param tracker the pointer tracker which pressed the parent key
-     * @return true if the long press is handled, false otherwise. Subclasses should call the
-     * method on the base class if the subclass doesn't wish to handle the call.
-     */
-    protected boolean onLongPress(Key parentKey, PointerTracker tracker) {
-        final int primaryCode = parentKey.mCode;
-        final Keyboard keyboard = getKeyboard();
-        if (keyboard instanceof LatinKeyboard) {
-            final LatinKeyboard latinKeyboard = (LatinKeyboard) keyboard;
-            if (primaryCode == Keyboard.CODE_DIGIT0 && latinKeyboard.isPhoneKeyboard()) {
-                tracker.onLongPressed();
-                // Long pressing on 0 in phone number keypad gives you a '+'.
-                return invokeOnKey(Keyboard.CODE_PLUS);
-            }
-            if (primaryCode == Keyboard.CODE_SHIFT && latinKeyboard.isAlphaKeyboard()) {
-                tracker.onLongPressed();
-                return invokeOnKey(Keyboard.CODE_CAPSLOCK);
-            }
-        }
-        if (primaryCode == Keyboard.CODE_SETTINGS || primaryCode == Keyboard.CODE_SPACE) {
-            // Both long pressing settings key and space key invoke IME switcher dialog.
-            if (getKeyboardActionListener().onCustomRequest(
-                    LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
-                tracker.onLongPressed();
-                return true;
-            } else {
-                return openPopupPanel(parentKey, tracker);
-            }
-        } else {
-            return openPopupPanel(parentKey, tracker);
-        }
-    }
-
-    private boolean invokeOnKey(int primaryCode) {
-        getKeyboardActionListener().onCodeInput(primaryCode, null,
-                KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
-                KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
-        return true;
-    }
-
-    private boolean openPopupPanel(Key parentKey, PointerTracker tracker) {
-        PopupPanel popupPanel = mPopupPanelCache.get(parentKey);
-        if (popupPanel == null) {
-            popupPanel = onCreatePopupPanel(parentKey);
-            if (popupPanel == null)
-                return false;
-            mPopupPanelCache.put(parentKey, popupPanel);
-        }
-        if (mPopupWindow == null) {
-            mPopupWindow = new PopupWindow(getContext());
-            mPopupWindow.setBackgroundDrawable(null);
-            mPopupWindow.setAnimationStyle(R.style.PopupMiniKeyboardAnimation);
-            // Allow popup window to be drawn off the screen.
-            mPopupWindow.setClippingEnabled(false);
-        }
-        mPopupPanel = popupPanel;
-        mPopupPanelPointerTrackerId = tracker.mPointerId;
-
-        popupPanel.showPopupPanel(this, parentKey, tracker, mPopupWindow);
-        final int translatedX = popupPanel.translateX(tracker.getLastX());
-        final int translatedY = popupPanel.translateY(tracker.getLastY());
-        tracker.onShowPopupPanel(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
-
-        invalidateAllKeys();
-        return true;
-    }
-
-    private PointerTracker getPointerTracker(final int id) {
-        return PointerTracker.getPointerTracker(id, this);
-    }
-
-    public boolean isInSlidingKeyInput() {
-        if (mPopupPanel != null) {
-            return true;
-        } else {
-            return PointerTracker.isAnyInSlidingKeyInput();
-        }
-    }
-
-    public int getPointerCount() {
-        return mOldPointerCount;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent me) {
-        final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
-        final int action = me.getActionMasked();
-        final int pointerCount = me.getPointerCount();
-        final int oldPointerCount = mOldPointerCount;
-        mOldPointerCount = pointerCount;
-
-        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
-        // If the device does not have distinct multi-touch support panel, ignore all multi-touch
-        // events except a transition from/to single-touch.
-        if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
-            return true;
-        }
-
-        // Gesture detector must be enabled only when mini-keyboard is not on the screen.
-        if (mPopupPanel == null && mGestureDetector != null
-                && mGestureDetector.onTouchEvent(me)) {
-            PointerTracker.dismissAllKeyPreviews();
-            mKeyTimerHandler.cancelKeyTimers();
-            return true;
-        }
-
-        final long eventTime = me.getEventTime();
-        final int index = me.getActionIndex();
-        final int id = me.getPointerId(index);
-        final int x, y;
-        if (mPopupPanel != null && id == mPopupPanelPointerTrackerId) {
-            x = mPopupPanel.translateX((int)me.getX(index));
-            y = mPopupPanel.translateY((int)me.getY(index));
-        } else {
-            x = (int)me.getX(index);
-            y = (int)me.getY(index);
-        }
-
-        if (mKeyTimerHandler.isInKeyRepeat()) {
-            final PointerTracker tracker = getPointerTracker(id);
-            // Key repeating timer will be canceled if 2 or more keys are in action, and current
-            // event (UP or DOWN) is non-modifier key.
-            if (pointerCount > 1 && !tracker.isModifier()) {
-                mKeyTimerHandler.cancelKeyRepeatTimer();
-            }
-            // Up event will pass through.
-        }
-
-        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
-        // Translate mutli-touch event to single-touch events on the device that has no distinct
-        // multi-touch panel.
-        if (nonDistinctMultitouch) {
-            // Use only main (id=0) pointer tracker.
-            PointerTracker tracker = getPointerTracker(0);
-            if (pointerCount == 1 && oldPointerCount == 2) {
-                // Multi-touch to single touch transition.
-                // Send a down event for the latest pointer if the key is different from the
-                // previous key.
-                final int newKeyIndex = tracker.getKeyIndexOn(x, y);
-                if (mOldKeyIndex != newKeyIndex) {
-                    tracker.onDownEvent(x, y, eventTime, this);
-                    if (action == MotionEvent.ACTION_UP)
-                        tracker.onUpEvent(x, y, eventTime);
-                }
-            } else if (pointerCount == 2 && oldPointerCount == 1) {
-                // Single-touch to multi-touch transition.
-                // Send an up event for the last pointer.
-                final int lastX = tracker.getLastX();
-                final int lastY = tracker.getLastY();
-                mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
-                tracker.onUpEvent(lastX, lastY, eventTime);
-            } else if (pointerCount == 1 && oldPointerCount == 1) {
-                processMotionEvent(tracker, action, x, y, eventTime, this);
-            } else {
-                Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
-                        + " (old " + oldPointerCount + ")");
-            }
-            return true;
-        }
-
-        if (action == MotionEvent.ACTION_MOVE) {
-            for (int i = 0; i < pointerCount; i++) {
-                final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
-                final int px, py;
-                if (mPopupPanel != null && tracker.mPointerId == mPopupPanelPointerTrackerId) {
-                    px = mPopupPanel.translateX((int)me.getX(i));
-                    py = mPopupPanel.translateY((int)me.getY(i));
-                } else {
-                    px = (int)me.getX(i);
-                    py = (int)me.getY(i);
-                }
-                tracker.onMoveEvent(px, py, eventTime);
-            }
-        } else {
-            processMotionEvent(getPointerTracker(id), action, x, y, eventTime, this);
-        }
-
-        return true;
-    }
-
-    private static void processMotionEvent(PointerTracker tracker, int action, int x, int y,
-            long eventTime, PointerTracker.KeyEventHandler handler) {
-        switch (action) {
-        case MotionEvent.ACTION_DOWN:
-        case MotionEvent.ACTION_POINTER_DOWN:
-            tracker.onDownEvent(x, y, eventTime, handler);
-            break;
-        case MotionEvent.ACTION_UP:
-        case MotionEvent.ACTION_POINTER_UP:
-            tracker.onUpEvent(x, y, eventTime);
-            break;
-        case MotionEvent.ACTION_MOVE:
-            tracker.onMoveEvent(x, y, eventTime);
-            break;
-        case MotionEvent.ACTION_CANCEL:
-            tracker.onCancelEvent(x, y, eventTime);
-            break;
-        }
-    }
-
-    @Override
-    public void closing() {
-        super.closing();
-        dismissPopupPanel();
-        mPopupPanelCache.clear();
-    }
-
-    @Override
-    public boolean dismissPopupPanel() {
-        if (mPopupWindow != null && mPopupWindow.isShowing()) {
-            mPopupWindow.dismiss();
-            mPopupPanel = null;
-            mPopupPanelPointerTrackerId = -1;
-            invalidateAllKeys();
-            return true;
-        }
-        return false;
-    }
-
-    public boolean handleBack() {
-        return dismissPopupPanel();
-    }
-
-    @Override
-    public void draw(Canvas c) {
-        Utils.GCUtils.getInstance().reset();
-        boolean tryGC = true;
-        for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
-            try {
-                super.draw(c);
-                tryGC = false;
-            } catch (OutOfMemoryError e) {
-                tryGC = Utils.GCUtils.getInstance().tryGCOrWait("LatinKeyboardView", e);
-            }
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        // Token is available from here.
-        VoiceProxy.getInstance().onAttachedToWindow();
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        // Drop non-hover touch events when touch exploration is enabled.
-        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
-            return false;
-        }
-
-        return super.dispatchTouchEvent(event);
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
-            final PointerTracker tracker = getPointerTracker(0);
-            return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent(
-                    event, tracker) || super.dispatchPopulateAccessibilityEvent(event);
-        }
-
-        return super.dispatchPopulateAccessibilityEvent(event);
-    }
-
-    /**
-     * Receives hover events from the input framework. This method overrides
-     * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On
-     * lower SDK versions, this method is never called.
-     *
-     * @param event The motion event to be dispatched.
-     * @return {@code true} if the event was handled by the view, {@code false}
-     *         otherwise
-     */
-    public boolean dispatchHoverEvent(MotionEvent event) {
-        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
-            final PointerTracker tracker = getPointerTracker(0);
-            return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker);
-        }
-
-        // Reflection doesn't support calling superclass methods.
-        return false;
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 42ce7c4..be04b5a 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -1,152 +1,691 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 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
+ * 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
+ *      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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package com.android.inputmethod.keyboard;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.os.Message;
+import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.PopupWindow;
 
-import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
 import com.android.inputmethod.latin.Utils;
 
-// TODO: We should remove this class
-public class LatinKeyboardView extends LatinKeyboardBaseView {
-    private static final String TAG = LatinKeyboardView.class.getSimpleName();
-    private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
+import java.util.WeakHashMap;
 
-    /** Whether we've started dropping move events because we found a big jump */
-    private boolean mDroppingEvents;
-    /**
-     * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
-     * occured
-     */
-    private boolean mDisableDisambiguation;
-    /** The distance threshold at which we start treating the touch session as a multi-touch */
-    private int mJumpThresholdSquare = Integer.MAX_VALUE;
-    private int mLastX;
-    private int mLastY;
+/**
+ * A view that is responsible for detecting key presses and touch movements.
+ *
+ * @attr ref R.styleable#KeyboardView_keyHysteresisDistance
+ * @attr ref R.styleable#KeyboardView_verticalCorrection
+ * @attr ref R.styleable#KeyboardView_popupLayout
+ */
+public class LatinKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
+        SuddenJumpingTouchEventHandler.ProcessMotionEvent {
+    private static final String TAG = LatinKeyboardView.class.getSimpleName();
+
+    private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
+
+    private final SuddenJumpingTouchEventHandler mTouchScreenRegulator;
+
+    // Timing constants
+    private final int mKeyRepeatInterval;
+
+    // XML attribute
+    private final float mVerticalCorrection;
+    private final int mPopupLayout;
+
+    // Mini keyboard
+    private PopupWindow mPopupWindow;
+    private PopupPanel mPopupPanel;
+    private int mPopupPanelPointerTrackerId;
+    private final WeakHashMap<Key, PopupPanel> mPopupPanelCache =
+            new WeakHashMap<Key, PopupPanel>();
+
+    /** Listener for {@link KeyboardActionListener}. */
+    private KeyboardActionListener mKeyboardActionListener;
+
+    private final boolean mHasDistinctMultitouch;
+    private int mOldPointerCount = 1;
+    private int mOldKeyIndex;
+
+    protected KeyDetector mKeyDetector;
+
+    // To detect double tap.
+    protected GestureDetector mGestureDetector;
+
+    private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
+
+    private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView>
+            implements TimerProxy {
+        private static final int MSG_REPEAT_KEY = 1;
+        private static final int MSG_LONGPRESS_KEY = 2;
+        private static final int MSG_IGNORE_DOUBLE_TAP = 3;
+
+        private boolean mInKeyRepeat;
+
+        public KeyTimerHandler(LatinKeyboardView outerInstance) {
+            super(outerInstance);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final LatinKeyboardView keyboardView = getOuterInstance();
+            final PointerTracker tracker = (PointerTracker) msg.obj;
+            switch (msg.what) {
+            case MSG_REPEAT_KEY:
+                tracker.onRepeatKey(msg.arg1);
+                startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker);
+                break;
+            case MSG_LONGPRESS_KEY:
+                keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker);
+                break;
+            }
+        }
+
+        @Override
+        public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
+            mInKeyRepeat = true;
+            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
+        }
+
+        public void cancelKeyRepeatTimer() {
+            mInKeyRepeat = false;
+            removeMessages(MSG_REPEAT_KEY);
+        }
+
+        public boolean isInKeyRepeat() {
+            return mInKeyRepeat;
+        }
+
+        @Override
+        public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
+            cancelLongPressTimer();
+            sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
+        }
+
+        @Override
+        public void cancelLongPressTimer() {
+            removeMessages(MSG_LONGPRESS_KEY);
+        }
+
+        @Override
+        public void cancelKeyTimers() {
+            cancelKeyRepeatTimer();
+            cancelLongPressTimer();
+            removeMessages(MSG_IGNORE_DOUBLE_TAP);
+        }
+
+        public void startIgnoringDoubleTap() {
+            sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
+                    ViewConfiguration.getDoubleTapTimeout());
+        }
+
+        public boolean isIgnoringDoubleTap() {
+            return hasMessages(MSG_IGNORE_DOUBLE_TAP);
+        }
+
+        public void cancelAllMessages() {
+            cancelKeyTimers();
+        }
+    }
+
+    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
+        private boolean mProcessingShiftDoubleTapEvent = false;
+
+        @Override
+        public boolean onDoubleTap(MotionEvent firstDown) {
+            final Keyboard keyboard = getKeyboard();
+            if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard instanceof LatinKeyboard
+                    && ((LatinKeyboard) keyboard).isAlphaKeyboard()) {
+                final int pointerIndex = firstDown.getActionIndex();
+                final int id = firstDown.getPointerId(pointerIndex);
+                final PointerTracker tracker = getPointerTracker(id);
+                // If the first down event is on shift key.
+                if (tracker.isOnShiftKey((int) firstDown.getX(), (int) firstDown.getY())) {
+                    mProcessingShiftDoubleTapEvent = true;
+                    return true;
+                }
+            }
+            mProcessingShiftDoubleTapEvent = false;
+            return false;
+        }
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent secondTap) {
+            if (mProcessingShiftDoubleTapEvent
+                    && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
+                final MotionEvent secondDown = secondTap;
+                final int pointerIndex = secondDown.getActionIndex();
+                final int id = secondDown.getPointerId(pointerIndex);
+                final PointerTracker tracker = getPointerTracker(id);
+                // If the second down event is also on shift key.
+                if (tracker.isOnShiftKey((int) secondDown.getX(), (int) secondDown.getY())) {
+                    // Detected a double tap on shift key. If we are in the ignoring double tap
+                    // mode, it means we have already turned off caps lock in
+                    // {@link KeyboardSwitcher#onReleaseShift} .
+                    final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
+                    if (!ignoringDoubleTap)
+                        onDoubleTapShiftKey(tracker);
+                    return true;
+                }
+                // Otherwise these events should not be handled as double tap.
+                mProcessingShiftDoubleTapEvent = false;
+            }
+            return mProcessingShiftDoubleTapEvent;
+        }
+    }
 
     public LatinKeyboardView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, R.attr.keyboardViewStyle);
     }
 
     public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+
+        mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+        mVerticalCorrection = a.getDimensionPixelOffset(
+                R.styleable.KeyboardView_verticalCorrection, 0);
+        mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
+        a.recycle();
+
+        final Resources res = getResources();
+        final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance);
+        mKeyDetector = new KeyDetector(keyHysteresisDistance);
+
+        final boolean ignoreMultitouch = true;
+        mGestureDetector = new GestureDetector(
+                getContext(), new DoubleTapListener(), null, ignoreMultitouch);
+        mGestureDetector.setIsLongpressEnabled(false);
+
+        mHasDistinctMultitouch = context.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
+        mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+
+        PointerTracker.init(mHasDistinctMultitouch, getContext());
     }
 
-    @Override
-    public void setKeyboard(Keyboard newKeyboard) {
-        super.setKeyboard(newKeyboard);
-        // One-seventh of the keyboard width seems like a reasonable threshold
-        final int jumpThreshold = newKeyboard.mOccupiedWidth / 7;
-        mJumpThresholdSquare = jumpThreshold * jumpThreshold;
+    public void startIgnoringDoubleTap() {
+        if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
+            mKeyTimerHandler.startIgnoringDoubleTap();
+    }
+
+    public void setKeyboardActionListener(KeyboardActionListener listener) {
+        mKeyboardActionListener = listener;
+        PointerTracker.setKeyboardActionListener(listener);
     }
 
     /**
-     * This function checks to see if we need to handle any sudden jumps in the pointer location
-     * that could be due to a multi-touch being treated as a move by the firmware or hardware.
-     * Once a sudden jump is detected, all subsequent move events are discarded
-     * until an UP is received.<P>
-     * When a sudden jump is detected, an UP event is simulated at the last position and when
-     * the sudden moves subside, a DOWN event is simulated for the second key.
-     * @param me the motion event
-     * @return true if the event was consumed, so that it doesn't continue to be handled by
-     * {@link LatinKeyboardBaseView}.
+     * Returns the {@link KeyboardActionListener} object.
+     * @return the listener attached to this keyboard
      */
-    private boolean handleSuddenJump(MotionEvent me) {
-        // If device has distinct multi touch panel, there is no need to check sudden jump.
-        if (hasDistinctMultitouch())
-            return false;
-        final int action = me.getAction();
-        final int x = (int) me.getX();
-        final int y = (int) me.getY();
-        boolean result = false;
+    @Override
+    public KeyboardActionListener getKeyboardActionListener() {
+        return mKeyboardActionListener;
+    }
 
-        // Real multi-touch event? Stop looking for sudden jumps
-        if (me.getPointerCount() > 1) {
-            mDisableDisambiguation = true;
+    @Override
+    public KeyDetector getKeyDetector() {
+        return mKeyDetector;
+    }
+
+    @Override
+    public DrawingProxy getDrawingProxy() {
+        return this;
+    }
+
+    @Override
+    public TimerProxy getTimerProxy() {
+        return mKeyTimerHandler;
+    }
+
+    @Override
+    public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+        final Keyboard keyboard = getKeyboard();
+        if (keyboard instanceof LatinKeyboard) {
+            final LatinKeyboard latinKeyboard = (LatinKeyboard)keyboard;
+            if (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard()) {
+                // Phone and number keyboard never shows popup preview.
+                super.setKeyPreviewPopupEnabled(false, delay);
+                return;
+            }
         }
-        if (mDisableDisambiguation) {
-            // If UP, reset the multi-touch flag
-            if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
+        super.setKeyPreviewPopupEnabled(previewEnabled, delay);
+    }
+
+    /**
+     * Attaches a keyboard to this view. The keyboard can be switched at any time and the
+     * view will re-layout itself to accommodate the keyboard.
+     * @see Keyboard
+     * @see #getKeyboard()
+     * @param keyboard the keyboard to display in this view
+     */
+    @Override
+    public void setKeyboard(Keyboard keyboard) {
+        // Remove any pending messages, except dismissing preview
+        mKeyTimerHandler.cancelKeyTimers();
+        super.setKeyboard(keyboard);
+        mKeyDetector.setKeyboard(
+                keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
+        mKeyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth);
+        PointerTracker.setKeyDetector(mKeyDetector);
+        mTouchScreenRegulator.setKeyboard(keyboard);
+        mPopupPanelCache.clear();
+    }
+
+    /**
+     * Returns whether the device has distinct multi-touch panel.
+     * @return true if the device has distinct multi-touch panel.
+     */
+    public boolean hasDistinctMultitouch() {
+        return mHasDistinctMultitouch;
+    }
+
+    /**
+     * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
+     * codes for adjacent keys.  When disabled, only the primary key code will be
+     * reported.
+     * @param enabled whether or not the proximity correction is enabled
+     */
+    public void setProximityCorrectionEnabled(boolean enabled) {
+        mKeyDetector.setProximityCorrectionEnabled(enabled);
+    }
+
+    /**
+     * Returns true if proximity correction is enabled.
+     */
+    public boolean isProximityCorrectionEnabled() {
+        return mKeyDetector.isProximityCorrectionEnabled();
+    }
+
+    @Override
+    public void cancelAllMessages() {
+        mKeyTimerHandler.cancelAllMessages();
+        super.cancelAllMessages();
+    }
+
+    private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) {
+        // Check if we have a popup layout specified first.
+        if (mPopupLayout == 0) {
             return false;
         }
 
-        switch (action) {
-        case MotionEvent.ACTION_DOWN:
-            // Reset the "session"
-            mDroppingEvents = false;
-            mDisableDisambiguation = false;
-            break;
-        case MotionEvent.ACTION_MOVE:
-            // Is this a big jump?
-            final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
-            // Check the distance.
-            if (distanceSquare > mJumpThresholdSquare) {
-                // If we're not yet dropping events, start dropping and send an UP event
-                if (!mDroppingEvents) {
-                    mDroppingEvents = true;
-                    // Send an up event
-                    MotionEvent translated = MotionEvent.obtain(
-                            me.getEventTime(), me.getEventTime(),
-                            MotionEvent.ACTION_UP,
-                            mLastX, mLastY, me.getMetaState());
-                    super.onTouchEvent(translated);
-                    translated.recycle();
-                }
-                result = true;
-            } else if (mDroppingEvents) {
-                // If moves are small and we're already dropping events, continue dropping
-                result = true;
-            }
-            break;
-        case MotionEvent.ACTION_UP:
-            if (mDroppingEvents) {
-                // Send a down event first, as we dropped a bunch of sudden jumps and assume that
-                // the user is releasing the touch on the second key.
-                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
-                        MotionEvent.ACTION_DOWN,
-                        x, y, me.getMetaState());
-                super.onTouchEvent(translated);
-                translated.recycle();
-                mDroppingEvents = false;
-                // Let the up event get processed as well, result = false
-            }
-            break;
+        // Check if we are already displaying popup panel.
+        if (mPopupPanel != null)
+            return false;
+        final Key parentKey = tracker.getKey(keyIndex);
+        if (parentKey == null)
+            return false;
+        return onLongPress(parentKey, tracker);
+    }
+
+    private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
+        // When shift key is double tapped, the first tap is correctly processed as usual tap. And
+        // the second tap is treated as this double tap event, so that we need not mark tracker
+        // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
+        mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
+    }
+
+    // This default implementation returns a popup mini keyboard panel.
+    protected PopupPanel onCreatePopupPanel(Key parentKey) {
+        if (parentKey.mPopupCharacters == null)
+            return null;
+
+        final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null);
+        if (container == null)
+            throw new NullPointerException();
+
+        final PopupMiniKeyboardView miniKeyboardView =
+                (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
+        final Keyboard parentKeyboard = getKeyboard();
+        final Keyboard miniKeyboard = new MiniKeyboard.Builder(
+                this, parentKeyboard.mPopupKeyboardResId, parentKey, parentKeyboard).build();
+        miniKeyboardView.setKeyboard(miniKeyboard);
+
+        container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
+                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
+        return miniKeyboardView;
+    }
+
+    @Override
+    protected boolean needsToDimKeyboard() {
+        return mPopupPanel != null;
+    }
+
+    public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) {
+        final Keyboard keyboard = getKeyboard();
+        // We should not set text fade factor to the keyboard which does not display the language on
+        // its spacebar.
+        if (keyboard instanceof LatinKeyboard && keyboard == oldKeyboard) {
+            ((LatinKeyboard)keyboard).setSpacebarTextFadeFactor(fadeFactor, this);
         }
-        // Track the previous coordinate
-        mLastX = x;
-        mLastY = y;
-        return result;
+    }
+
+    /**
+     * Called when a key is long pressed. By default this will open mini keyboard associated
+     * with this key.
+     * @param parentKey the key that was long pressed
+     * @param tracker the pointer tracker which pressed the parent key
+     * @return true if the long press is handled, false otherwise. Subclasses should call the
+     * method on the base class if the subclass doesn't wish to handle the call.
+     */
+    protected boolean onLongPress(Key parentKey, PointerTracker tracker) {
+        final int primaryCode = parentKey.mCode;
+        final Keyboard keyboard = getKeyboard();
+        if (keyboard instanceof LatinKeyboard) {
+            final LatinKeyboard latinKeyboard = (LatinKeyboard) keyboard;
+            if (primaryCode == Keyboard.CODE_DIGIT0 && latinKeyboard.isPhoneKeyboard()) {
+                tracker.onLongPressed();
+                // Long pressing on 0 in phone number keypad gives you a '+'.
+                return invokeOnKey(Keyboard.CODE_PLUS);
+            }
+            if (primaryCode == Keyboard.CODE_SHIFT && latinKeyboard.isAlphaKeyboard()) {
+                tracker.onLongPressed();
+                return invokeOnKey(Keyboard.CODE_CAPSLOCK);
+            }
+        }
+        if (primaryCode == Keyboard.CODE_SETTINGS || primaryCode == Keyboard.CODE_SPACE) {
+            // Both long pressing settings key and space key invoke IME switcher dialog.
+            if (getKeyboardActionListener().onCustomRequest(
+                    LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
+                tracker.onLongPressed();
+                return true;
+            } else {
+                return openPopupPanel(parentKey, tracker);
+            }
+        } else {
+            return openPopupPanel(parentKey, tracker);
+        }
+    }
+
+    private boolean invokeOnKey(int primaryCode) {
+        getKeyboardActionListener().onCodeInput(primaryCode, null,
+                KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
+                KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
+        return true;
+    }
+
+    private boolean openPopupPanel(Key parentKey, PointerTracker tracker) {
+        PopupPanel popupPanel = mPopupPanelCache.get(parentKey);
+        if (popupPanel == null) {
+            popupPanel = onCreatePopupPanel(parentKey);
+            if (popupPanel == null)
+                return false;
+            mPopupPanelCache.put(parentKey, popupPanel);
+        }
+        if (mPopupWindow == null) {
+            mPopupWindow = new PopupWindow(getContext());
+            mPopupWindow.setBackgroundDrawable(null);
+            mPopupWindow.setAnimationStyle(R.style.PopupMiniKeyboardAnimation);
+            // Allow popup window to be drawn off the screen.
+            mPopupWindow.setClippingEnabled(false);
+        }
+        mPopupPanel = popupPanel;
+        mPopupPanelPointerTrackerId = tracker.mPointerId;
+
+        popupPanel.showPopupPanel(this, parentKey, tracker, mPopupWindow);
+        final int translatedX = popupPanel.translateX(tracker.getLastX());
+        final int translatedY = popupPanel.translateY(tracker.getLastY());
+        tracker.onShowPopupPanel(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
+
+        invalidateAllKeys();
+        return true;
+    }
+
+    private PointerTracker getPointerTracker(final int id) {
+        return PointerTracker.getPointerTracker(id, this);
+    }
+
+    public boolean isInSlidingKeyInput() {
+        if (mPopupPanel != null) {
+            return true;
+        } else {
+            return PointerTracker.isAnyInSlidingKeyInput();
+        }
+    }
+
+    public int getPointerCount() {
+        return mOldPointerCount;
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent me) {
-        if (getKeyboard() == null) return true;
+        return mTouchScreenRegulator.onTouchEvent(me);
+    }
 
-        // If there was a sudden jump, return without processing the actual motion event.
-        if (handleSuddenJump(me)) {
-            if (DEBUG_MODE)
-                Log.w(TAG, "onTouchEvent: ignore sudden jump " + me);
+    @Override
+    public boolean processMotionEvent(MotionEvent me) {
+        final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
+        final int action = me.getActionMasked();
+        final int pointerCount = me.getPointerCount();
+        final int oldPointerCount = mOldPointerCount;
+        mOldPointerCount = pointerCount;
+
+        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+        // If the device does not have distinct multi-touch support panel, ignore all multi-touch
+        // events except a transition from/to single-touch.
+        if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
             return true;
         }
 
-        return super.onTouchEvent(me);
+        // Gesture detector must be enabled only when mini-keyboard is not on the screen.
+        if (mPopupPanel == null && mGestureDetector != null
+                && mGestureDetector.onTouchEvent(me)) {
+            PointerTracker.dismissAllKeyPreviews();
+            mKeyTimerHandler.cancelKeyTimers();
+            return true;
+        }
+
+        final long eventTime = me.getEventTime();
+        final int index = me.getActionIndex();
+        final int id = me.getPointerId(index);
+        final int x, y;
+        if (mPopupPanel != null && id == mPopupPanelPointerTrackerId) {
+            x = mPopupPanel.translateX((int)me.getX(index));
+            y = mPopupPanel.translateY((int)me.getY(index));
+        } else {
+            x = (int)me.getX(index);
+            y = (int)me.getY(index);
+        }
+
+        if (mKeyTimerHandler.isInKeyRepeat()) {
+            final PointerTracker tracker = getPointerTracker(id);
+            // Key repeating timer will be canceled if 2 or more keys are in action, and current
+            // event (UP or DOWN) is non-modifier key.
+            if (pointerCount > 1 && !tracker.isModifier()) {
+                mKeyTimerHandler.cancelKeyRepeatTimer();
+            }
+            // Up event will pass through.
+        }
+
+        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+        // Translate mutli-touch event to single-touch events on the device that has no distinct
+        // multi-touch panel.
+        if (nonDistinctMultitouch) {
+            // Use only main (id=0) pointer tracker.
+            PointerTracker tracker = getPointerTracker(0);
+            if (pointerCount == 1 && oldPointerCount == 2) {
+                // Multi-touch to single touch transition.
+                // Send a down event for the latest pointer if the key is different from the
+                // previous key.
+                final int newKeyIndex = tracker.getKeyIndexOn(x, y);
+                if (mOldKeyIndex != newKeyIndex) {
+                    tracker.onDownEvent(x, y, eventTime, this);
+                    if (action == MotionEvent.ACTION_UP)
+                        tracker.onUpEvent(x, y, eventTime);
+                }
+            } else if (pointerCount == 2 && oldPointerCount == 1) {
+                // Single-touch to multi-touch transition.
+                // Send an up event for the last pointer.
+                final int lastX = tracker.getLastX();
+                final int lastY = tracker.getLastY();
+                mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
+                tracker.onUpEvent(lastX, lastY, eventTime);
+            } else if (pointerCount == 1 && oldPointerCount == 1) {
+                processMotionEvent(tracker, action, x, y, eventTime, this);
+            } else {
+                Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
+                        + " (old " + oldPointerCount + ")");
+            }
+            return true;
+        }
+
+        if (action == MotionEvent.ACTION_MOVE) {
+            for (int i = 0; i < pointerCount; i++) {
+                final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
+                final int px, py;
+                if (mPopupPanel != null && tracker.mPointerId == mPopupPanelPointerTrackerId) {
+                    px = mPopupPanel.translateX((int)me.getX(i));
+                    py = mPopupPanel.translateY((int)me.getY(i));
+                } else {
+                    px = (int)me.getX(i);
+                    py = (int)me.getY(i);
+                }
+                tracker.onMoveEvent(px, py, eventTime);
+            }
+        } else {
+            processMotionEvent(getPointerTracker(id), action, x, y, eventTime, this);
+        }
+
+        return true;
+    }
+
+    private static void processMotionEvent(PointerTracker tracker, int action, int x, int y,
+            long eventTime, PointerTracker.KeyEventHandler handler) {
+        switch (action) {
+        case MotionEvent.ACTION_DOWN:
+        case MotionEvent.ACTION_POINTER_DOWN:
+            tracker.onDownEvent(x, y, eventTime, handler);
+            break;
+        case MotionEvent.ACTION_UP:
+        case MotionEvent.ACTION_POINTER_UP:
+            tracker.onUpEvent(x, y, eventTime);
+            break;
+        case MotionEvent.ACTION_MOVE:
+            tracker.onMoveEvent(x, y, eventTime);
+            break;
+        case MotionEvent.ACTION_CANCEL:
+            tracker.onCancelEvent(x, y, eventTime);
+            break;
+        }
+    }
+
+    @Override
+    public void closing() {
+        super.closing();
+        dismissPopupPanel();
+        mPopupPanelCache.clear();
+    }
+
+    @Override
+    public boolean dismissPopupPanel() {
+        if (mPopupWindow != null && mPopupWindow.isShowing()) {
+            mPopupWindow.dismiss();
+            mPopupPanel = null;
+            mPopupPanelPointerTrackerId = -1;
+            invalidateAllKeys();
+            return true;
+        }
+        return false;
+    }
+
+    public boolean handleBack() {
+        return dismissPopupPanel();
+    }
+
+    @Override
+    public void draw(Canvas c) {
+        Utils.GCUtils.getInstance().reset();
+        boolean tryGC = true;
+        for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+            try {
+                super.draw(c);
+                tryGC = false;
+            } catch (OutOfMemoryError e) {
+                tryGC = Utils.GCUtils.getInstance().tryGCOrWait("LatinKeyboardView", e);
+            }
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        // Token is available from here.
+        VoiceProxy.getInstance().onAttachedToWindow();
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        // Drop non-hover touch events when touch exploration is enabled.
+        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+            return false;
+        }
+
+        return super.dispatchTouchEvent(event);
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+            final PointerTracker tracker = getPointerTracker(0);
+            return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent(
+                    event, tracker) || super.dispatchPopulateAccessibilityEvent(event);
+        }
+
+        return super.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    /**
+     * Receives hover events from the input framework. This method overrides
+     * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On
+     * lower SDK versions, this method is never called.
+     *
+     * @param event The motion event to be dispatched.
+     * @return {@code true} if the event was handled by the view, {@code false}
+     *         otherwise
+     */
+    public boolean dispatchHoverEvent(MotionEvent event) {
+        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+            final PointerTracker tracker = getPointerTracker(0);
+            return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker);
+        }
+
+        // Reflection doesn't support calling superclass methods.
+        return false;
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 08e7d7e..17c2539 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -16,12 +16,18 @@
 
 package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder.MiniKeyboardParams;
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
+import com.android.inputmethod.keyboard.internal.KeyboardParams;
+import com.android.inputmethod.keyboard.internal.PopupCharactersParser;
+import com.android.inputmethod.latin.R;
 
 public class MiniKeyboard extends Keyboard {
     private final int mDefaultKeyCoordX;
 
-    public MiniKeyboard(MiniKeyboardParams params) {
+    private MiniKeyboard(Builder.MiniKeyboardParams params) {
         super(params);
         mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2;
     }
@@ -29,4 +35,244 @@
     public int getDefaultCoordX() {
         return mDefaultKeyCoordX;
     }
+
+    public static class Builder extends KeyboardBuilder<Builder.MiniKeyboardParams> {
+        private final CharSequence[] mPopupCharacters;
+
+        public static class MiniKeyboardParams extends KeyboardParams {
+            /* package */int mTopRowAdjustment;
+            public int mNumRows;
+            public int mNumColumns;
+            public int mLeftKeys;
+            public int mRightKeys; // includes default key.
+
+            public MiniKeyboardParams() {
+                super();
+            }
+
+            /* package for test */MiniKeyboardParams(int numKeys, int maxColumns, int keyWidth,
+                    int rowHeight, int coordXInParent, int parentKeyboardWidth) {
+                super();
+                setParameters(numKeys, maxColumns, keyWidth, rowHeight, coordXInParent,
+                        parentKeyboardWidth);
+            }
+
+            /**
+             * Set keyboard parameters of mini keyboard.
+             *
+             * @param numKeys number of keys in this mini keyboard.
+             * @param maxColumns number of maximum columns of this mini keyboard.
+             * @param keyWidth mini keyboard key width in pixel, including horizontal gap.
+             * @param rowHeight mini keyboard row height in pixel, including vertical gap.
+             * @param coordXInParent coordinate x of the popup key in parent keyboard.
+             * @param parentKeyboardWidth parent keyboard width in pixel.
+             */
+            public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
+                    int coordXInParent, int parentKeyboardWidth) {
+                if (parentKeyboardWidth / keyWidth < maxColumns) {
+                    throw new IllegalArgumentException(
+                            "Keyboard is too small to hold mini keyboard: " + parentKeyboardWidth
+                                    + " " + keyWidth + " " + maxColumns);
+                }
+                mDefaultKeyWidth = keyWidth;
+                mDefaultRowHeight = rowHeight;
+
+                final int numRows = (numKeys + maxColumns - 1) / maxColumns;
+                mNumRows = numRows;
+                final int numColumns = getOptimizedColumns(numKeys, maxColumns);
+                mNumColumns = numColumns;
+
+                final int numLeftKeys = (numColumns - 1) / 2;
+                final int numRightKeys = numColumns - numLeftKeys; // including default key.
+                final int maxLeftKeys = coordXInParent / keyWidth;
+                final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent)
+                        / keyWidth);
+                int leftKeys, rightKeys;
+                if (numLeftKeys > maxLeftKeys) {
+                    leftKeys = maxLeftKeys;
+                    rightKeys = numColumns - maxLeftKeys;
+                } else if (numRightKeys > maxRightKeys) {
+                    leftKeys = numColumns - maxRightKeys;
+                    rightKeys = maxRightKeys;
+                } else {
+                    leftKeys = numLeftKeys;
+                    rightKeys = numRightKeys;
+                }
+                // Shift right if the left edge of mini keyboard is on the edge of parent keyboard
+                // unless the parent key is on the left edge.
+                if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) {
+                    leftKeys--;
+                    rightKeys++;
+                }
+                // Shift left if the right edge of mini keyboard is on the edge of parent keyboard
+                // unless the parent key is on the right edge.
+                if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) {
+                    leftKeys++;
+                    rightKeys--;
+                }
+                mLeftKeys = leftKeys;
+                mRightKeys = rightKeys;
+
+                // Centering of the top row.
+                final boolean onEdge = (leftKeys == 0 || rightKeys == 1);
+                if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
+                    mTopRowAdjustment = 0;
+                } else if (mLeftKeys < mRightKeys - 1) {
+                    mTopRowAdjustment = 1;
+                } else {
+                    mTopRowAdjustment = -1;
+                }
+
+                mWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth;
+                mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
+            }
+
+            // Return key position according to column count (0 is default).
+            /* package */int getColumnPos(int n) {
+                final int col = n % mNumColumns;
+                if (col == 0) {
+                    // default position.
+                    return 0;
+                }
+                int pos = 0;
+                int right = 1; // include default position key.
+                int left = 0;
+                int i = 0;
+                while (true) {
+                    // Assign right key if available.
+                    if (right < mRightKeys) {
+                        pos = right;
+                        right++;
+                        i++;
+                    }
+                    if (i >= col)
+                        break;
+                    // Assign left key if available.
+                    if (left < mLeftKeys) {
+                        left++;
+                        pos = -left;
+                        i++;
+                    }
+                    if (i >= col)
+                        break;
+                }
+                return pos;
+            }
+
+            private static int getTopRowEmptySlots(int numKeys, int numColumns) {
+                final int remainingKeys = numKeys % numColumns;
+                if (remainingKeys == 0) {
+                    return 0;
+                } else {
+                    return numColumns - remainingKeys;
+                }
+            }
+
+            private int getOptimizedColumns(int numKeys, int maxColumns) {
+                int numColumns = Math.min(numKeys, maxColumns);
+                while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) {
+                    numColumns--;
+                }
+                return numColumns;
+            }
+
+            public int getDefaultKeyCoordX() {
+                return mLeftKeys * mDefaultKeyWidth;
+            }
+
+            public int getX(int n, int row) {
+                final int x = getColumnPos(n) * mDefaultKeyWidth + getDefaultKeyCoordX();
+                if (isTopRow(row)) {
+                    return x + mTopRowAdjustment * (mDefaultKeyWidth / 2);
+                }
+                return x;
+            }
+
+            public int getY(int row) {
+                return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding;
+            }
+
+            public int getRowFlags(int row) {
+                int rowFlags = 0;
+                if (row == 0)
+                    rowFlags |= Keyboard.EDGE_TOP;
+                if (isTopRow(row))
+                    rowFlags |= Keyboard.EDGE_BOTTOM;
+                return rowFlags;
+            }
+
+            private boolean isTopRow(int rowCount) {
+                return rowCount == mNumRows - 1;
+            }
+        }
+
+        public Builder(KeyboardView view, int xmlId, Key parentKey, Keyboard parentKeyboard) {
+            super(view.getContext(), new MiniKeyboardParams());
+            load(parentKeyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
+
+            // HACK: Current mini keyboard design totally relies on the 9-patch
+            // padding about horizontal
+            // and vertical key spacing. To keep the visual of mini keyboard as
+            // is, these hacks are
+            // needed to keep having the same horizontal and vertical key
+            // spacing.
+            mParams.mHorizontalGap = 0;
+            mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
+            // TODO: When we have correctly padded key background 9-patch
+            // drawables for mini keyboard,
+            // revert the above hacks and uncomment the following lines.
+            // mParams.mHorizontalGap = parentKeyboard.mHorizontalGap;
+            // mParams.mVerticalGap = parentKeyboard.mVerticalGap;
+
+            mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
+            mPopupCharacters = parentKey.mPopupCharacters;
+
+            final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, mParams.mDefaultKeyWidth);
+            mParams.setParameters(mPopupCharacters.length, parentKey.mMaxPopupColumn, keyWidth,
+                    parentKeyboard.mDefaultRowHeight, parentKey.mX
+                            + (mParams.mDefaultKeyWidth - keyWidth) / 2, view.getMeasuredWidth());
+        }
+
+        private static int getMaxKeyWidth(KeyboardView view, CharSequence[] popupCharacters,
+                int minKeyWidth) {
+            Paint paint = null;
+            Rect bounds = null;
+            int maxWidth = 0;
+            for (CharSequence popupSpec : popupCharacters) {
+                final CharSequence label = PopupCharactersParser.getLabel(popupSpec.toString());
+                // If the label is single letter, minKeyWidth is enough to hold
+                // the label.
+                if (label != null && label.length() > 1) {
+                    if (paint == null) {
+                        paint = new Paint();
+                        paint.setAntiAlias(true);
+                    }
+                    final int labelSize = view.getDefaultLabelSizeAndSetPaint(paint);
+                    paint.setTextSize(labelSize);
+                    if (bounds == null)
+                        bounds = new Rect();
+                    paint.getTextBounds(label.toString(), 0, label.length(), bounds);
+                    if (maxWidth < bounds.width())
+                        maxWidth = bounds.width();
+                }
+            }
+            final int horizontalPadding = (int) view.getContext().getResources()
+                    .getDimension(R.dimen.mini_keyboard_key_horizontal_padding);
+            return Math.max(minKeyWidth, maxWidth + horizontalPadding);
+        }
+
+        @Override
+        public MiniKeyboard build() {
+            final MiniKeyboardParams params = mParams;
+            for (int n = 0; n < mPopupCharacters.length; n++) {
+                final CharSequence label = mPopupCharacters[n];
+                final int row = n / params.mNumColumns;
+                final Key key = new Key(mResources, params, label, params.getX(n, row),
+                        params.getY(row), params.mDefaultKeyWidth, params.mDefaultRowHeight,
+                        params.getRowFlags(row));
+                params.onAddKey(key);
+            }
+            return new MiniKeyboard(params);
+        }
+    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
deleted file mode 100644
index 84bd44c..0000000
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.inputmethod.keyboard;
-
-import java.util.List;
-
-public class MiniKeyboardKeyDetector extends KeyDetector {
-    private final int mSlideAllowanceSquare;
-    private final int mSlideAllowanceSquareTop;
-
-    public MiniKeyboardKeyDetector(float slideAllowance) {
-        super(/* keyHysteresisDistance */0);
-        mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
-        // Top slide allowance is slightly longer (sqrt(2) times) than other edges.
-        mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
-    }
-
-    @Override
-    protected int getMaxNearbyKeys() {
-        // No nearby key will be returned.
-        return 1;
-    }
-
-    @Override
-    public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
-        final List<Key> keys = getKeyboard().mKeys;
-        final int touchX = getTouchX(x);
-        final int touchY = getTouchY(y);
-
-        int nearestIndex = NOT_A_KEY;
-        int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
-        final int keyCount = keys.size();
-        for (int index = 0; index < keyCount; index++) {
-            final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
-            if (dist < nearestDist) {
-                nearestIndex = index;
-                nearestDist = dist;
-            }
-        }
-
-        if (allCodes != null && nearestIndex != NOT_A_KEY)
-            allCodes[0] = keys.get(nearestIndex).mCode;
-        return nearestIndex;
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 1f8119a..d33cb44 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -438,9 +438,9 @@
     private void onDownEventInternal(int x, int y, long eventTime) {
         int keyIndex = onDownKey(x, y, eventTime);
         // Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
-        // from modifier key, or 3) this pointer is on mini-keyboard.
+        // from modifier key, or 3) this pointer's KeyDetector always allows sliding input.
         mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
-                || mKeyDetector instanceof MiniKeyboardKeyDetector;
+                || mKeyDetector.alwaysAllowsSlidingInput();
         mKeyboardLayoutHasBeenChanged = false;
         mKeyAlreadyProcessed = false;
         mIsRepeatableKey = false;
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index fb932e3..2396222 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -28,6 +28,8 @@
 import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
 import com.android.inputmethod.latin.R;
 
+import java.util.List;
+
 /**
  * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting
  * key presses and touch movements.
@@ -39,10 +41,55 @@
     private final KeyDetector mKeyDetector;
     private final int mVerticalCorrection;
 
-    private LatinKeyboardBaseView mParentKeyboardView;
+    private LatinKeyboardView mParentKeyboardView;
     private int mOriginX;
     private int mOriginY;
 
+    private static class MiniKeyboardKeyDetector extends KeyDetector {
+        private final int mSlideAllowanceSquare;
+        private final int mSlideAllowanceSquareTop;
+
+        public MiniKeyboardKeyDetector(float slideAllowance) {
+            super(/* keyHysteresisDistance */0);
+            mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
+            // Top slide allowance is slightly longer (sqrt(2) times) than other edges.
+            mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
+        }
+
+        @Override
+        public boolean alwaysAllowsSlidingInput() {
+            return true;
+        }
+
+        @Override
+        protected int getMaxNearbyKeys() {
+            // No nearby key will be returned.
+            return 1;
+        }
+
+        @Override
+        public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
+            final List<Key> keys = getKeyboard().mKeys;
+            final int touchX = getTouchX(x);
+            final int touchY = getTouchY(y);
+
+            int nearestIndex = NOT_A_KEY;
+            int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
+            final int keyCount = keys.size();
+            for (int index = 0; index < keyCount; index++) {
+                final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
+                if (dist < nearestDist) {
+                    nearestIndex = index;
+                    nearestDist = dist;
+                }
+            }
+
+            if (allCodes != null && nearestIndex != NOT_A_KEY)
+                allCodes[0] = keys.get(nearestIndex).mCode;
+            return nearestIndex;
+        }
+    }
+
     private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy() {
         @Override
         public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
@@ -146,11 +193,6 @@
     }
 
     @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        // Do nothing for the mini keyboard.
-    }
-
-    @Override
     public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
         // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a
         // delay of 0. The delay does not matter actually since the popup is not shown anyway.
@@ -158,7 +200,7 @@
     }
 
     @Override
-    public void showPopupPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+    public void showPopupPanel(LatinKeyboardView parentKeyboardView, Key parentKey,
             PointerTracker tracker, PopupWindow window) {
         mParentKeyboardView = parentKeyboardView;
         final View container = (View)getParent();
diff --git a/java/src/com/android/inputmethod/keyboard/PopupPanel.java b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
index dc526e7..db637c5 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
@@ -26,7 +26,7 @@
      * @param tracker the pointer tracker that pressesd the parent key
      * @param window PopupWindow to be used to show this popup panel
      */
-    public void showPopupPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+    public void showPopupPanel(LatinKeyboardView parentKeyboardView, Key parentKey,
             PointerTracker tracker, PopupWindow window);
 
     /**
diff --git a/java/src/com/android/inputmethod/keyboard/SuddenJumpingTouchEventHandler.java b/java/src/com/android/inputmethod/keyboard/SuddenJumpingTouchEventHandler.java
new file mode 100644
index 0000000..c4251cc
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/SuddenJumpingTouchEventHandler.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+
+public class SuddenJumpingTouchEventHandler {
+    private static final String TAG = SuddenJumpingTouchEventHandler.class.getSimpleName();
+    private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
+
+    public interface ProcessMotionEvent {
+        public boolean processMotionEvent(MotionEvent me);
+    }
+
+    private final ProcessMotionEvent mView;
+    private final boolean mNeedsSuddenJumpingHack;
+
+    /** Whether we've started dropping move events because we found a big jump */
+    private boolean mDroppingEvents;
+    /**
+     * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
+     * occured
+     */
+    private boolean mDisableDisambiguation;
+    /** The distance threshold at which we start treating the touch session as a multi-touch */
+    private int mJumpThresholdSquare = Integer.MAX_VALUE;
+    private int mLastX;
+    private int mLastY;
+
+    public SuddenJumpingTouchEventHandler(Context context, ProcessMotionEvent view) {
+        mView = view;
+        final String[] deviceList = context.getResources().getStringArray(
+                R.array.sudden_jumping_touch_event_device_list);
+        mNeedsSuddenJumpingHack = needsSuddenJumpingHack(Build.DEVICE, deviceList);
+    }
+
+    private static boolean needsSuddenJumpingHack(String deviceName, String[] deviceList) {
+        for (String device : deviceList) {
+            if (device.equalsIgnoreCase(deviceName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void setKeyboard(Keyboard newKeyboard) {
+        // One-seventh of the keyboard width seems like a reasonable threshold
+        final int jumpThreshold = newKeyboard.mOccupiedWidth / 7;
+        mJumpThresholdSquare = jumpThreshold * jumpThreshold;
+    }
+
+    /**
+     * This function checks to see if we need to handle any sudden jumps in the pointer location
+     * that could be due to a multi-touch being treated as a move by the firmware or hardware.
+     * Once a sudden jump is detected, all subsequent move events are discarded
+     * until an UP is received.<P>
+     * When a sudden jump is detected, an UP event is simulated at the last position and when
+     * the sudden moves subside, a DOWN event is simulated for the second key.
+     * @param me the motion event
+     * @return true if the event was consumed, so that it doesn't continue to be handled by
+     * {@link LatinKeyboardView}.
+     */
+    private boolean handleSuddenJumping(MotionEvent me) {
+        if (!mNeedsSuddenJumpingHack)
+            return false;
+        final int action = me.getAction();
+        final int x = (int) me.getX();
+        final int y = (int) me.getY();
+        boolean result = false;
+
+        // Real multi-touch event? Stop looking for sudden jumps
+        if (me.getPointerCount() > 1) {
+            mDisableDisambiguation = true;
+        }
+        if (mDisableDisambiguation) {
+            // If UP, reset the multi-touch flag
+            if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
+            return false;
+        }
+
+        switch (action) {
+        case MotionEvent.ACTION_DOWN:
+            // Reset the "session"
+            mDroppingEvents = false;
+            mDisableDisambiguation = false;
+            break;
+        case MotionEvent.ACTION_MOVE:
+            // Is this a big jump?
+            final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
+            // Check the distance.
+            if (distanceSquare > mJumpThresholdSquare) {
+                // If we're not yet dropping events, start dropping and send an UP event
+                if (!mDroppingEvents) {
+                    mDroppingEvents = true;
+                    // Send an up event
+                    MotionEvent translated = MotionEvent.obtain(
+                            me.getEventTime(), me.getEventTime(),
+                            MotionEvent.ACTION_UP,
+                            mLastX, mLastY, me.getMetaState());
+                    mView.processMotionEvent(translated);
+                    translated.recycle();
+                }
+                result = true;
+            } else if (mDroppingEvents) {
+                // If moves are small and we're already dropping events, continue dropping
+                result = true;
+            }
+            break;
+        case MotionEvent.ACTION_UP:
+            if (mDroppingEvents) {
+                // Send a down event first, as we dropped a bunch of sudden jumps and assume that
+                // the user is releasing the touch on the second key.
+                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+                        MotionEvent.ACTION_DOWN,
+                        x, y, me.getMetaState());
+                mView.processMotionEvent(translated);
+                translated.recycle();
+                mDroppingEvents = false;
+                // Let the up event get processed as well, result = false
+            }
+            break;
+        }
+        // Track the previous coordinate
+        mLastX = x;
+        mLastY = y;
+        return result;
+    }
+
+    public boolean onTouchEvent(MotionEvent me) {
+        // If there was a sudden jump, return without processing the actual motion event.
+        if (handleSuddenJumping(me)) {
+            if (DEBUG_MODE)
+                Log.w(TAG, "onTouchEvent: ignore sudden jump " + me);
+            return true;
+        }
+        return mView.processMotionEvent(me);
+    }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java
deleted file mode 100644
index 31a291c..0000000
--- a/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.inputmethod.keyboard.internal;
-
-import android.graphics.Paint;
-import android.graphics.Rect;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.MiniKeyboard;
-import com.android.inputmethod.latin.R;
-
-public class MiniKeyboardBuilder extends
-        KeyboardBuilder<MiniKeyboardBuilder.MiniKeyboardParams> {
-    private final CharSequence[] mPopupCharacters;
-
-    public static class MiniKeyboardParams extends KeyboardParams {
-        /* package */ int mTopRowAdjustment;
-        public int mNumRows;
-        public int mNumColumns;
-        public int mLeftKeys;
-        public int mRightKeys; // includes default key.
-
-        public MiniKeyboardParams() {
-            super();
-        }
-
-        /* package for test */ MiniKeyboardParams(int numKeys, int maxColumns, int keyWidth,
-                int rowHeight, int coordXInParent, int parentKeyboardWidth) {
-            super();
-            setParameters(
-                    numKeys, maxColumns, keyWidth, rowHeight, coordXInParent, parentKeyboardWidth);
-        }
-
-        /**
-         * Set keyboard parameters of mini keyboard.
-         *
-         * @param numKeys number of keys in this mini keyboard.
-         * @param maxColumns number of maximum columns of this mini keyboard.
-         * @param keyWidth mini keyboard key width in pixel, including horizontal gap.
-         * @param rowHeight mini keyboard row height in pixel, including vertical gap.
-         * @param coordXInParent coordinate x of the popup key in parent keyboard.
-         * @param parentKeyboardWidth parent keyboard width in pixel.
-         */
-        public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
-                int coordXInParent, int parentKeyboardWidth) {
-            if (parentKeyboardWidth / keyWidth < maxColumns) {
-                throw new IllegalArgumentException("Keyboard is too small to hold mini keyboard: "
-                        + parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
-            }
-            mDefaultKeyWidth = keyWidth;
-            mDefaultRowHeight = rowHeight;
-
-            final int numRows = (numKeys + maxColumns - 1) / maxColumns;
-            mNumRows = numRows;
-            final int numColumns = getOptimizedColumns(numKeys, maxColumns);
-            mNumColumns = numColumns;
-
-            final int numLeftKeys = (numColumns - 1) / 2;
-            final int numRightKeys = numColumns - numLeftKeys; // including default key.
-            final int maxLeftKeys = coordXInParent / keyWidth;
-            final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent) / keyWidth);
-            int leftKeys, rightKeys;
-            if (numLeftKeys > maxLeftKeys) {
-                leftKeys = maxLeftKeys;
-                rightKeys = numColumns - maxLeftKeys;
-            } else if (numRightKeys > maxRightKeys) {
-                leftKeys = numColumns - maxRightKeys;
-                rightKeys = maxRightKeys;
-            } else {
-                leftKeys = numLeftKeys;
-                rightKeys = numRightKeys;
-            }
-            // Shift right if the left edge of mini keyboard is on the edge of parent keyboard
-            // unless the parent key is on the left edge.
-            if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) {
-                leftKeys--;
-                rightKeys++;
-            }
-            // Shift left if the right edge of mini keyboard is on the edge of parent keyboard
-            // unless the parent key is on the right edge.
-            if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) {
-                leftKeys++;
-                rightKeys--;
-            }
-            mLeftKeys = leftKeys;
-            mRightKeys = rightKeys;
-
-            // Centering of the top row.
-            final boolean onEdge = (leftKeys == 0 || rightKeys == 1);
-            if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
-                mTopRowAdjustment = 0;
-            } else if (mLeftKeys < mRightKeys - 1) {
-                mTopRowAdjustment = 1;
-            } else {
-                mTopRowAdjustment = -1;
-            }
-
-            mWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth;
-            mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
-        }
-
-        // Return key position according to column count (0 is default).
-        /* package */ int getColumnPos(int n) {
-            final int col = n % mNumColumns;
-            if (col == 0) {
-                // default position.
-                return 0;
-            }
-            int pos = 0;
-            int right = 1; // include default position key.
-            int left = 0;
-            int i = 0;
-            while (true) {
-                // Assign right key if available.
-                if (right < mRightKeys) {
-                    pos = right;
-                    right++;
-                    i++;
-                }
-                if (i >= col)
-                    break;
-                // Assign left key if available.
-                if (left < mLeftKeys) {
-                    left++;
-                    pos = -left;
-                    i++;
-                }
-                if (i >= col)
-                    break;
-            }
-            return pos;
-        }
-
-        private static int getTopRowEmptySlots(int numKeys, int numColumns) {
-            final int remainingKeys = numKeys % numColumns;
-            if (remainingKeys == 0) {
-                return 0;
-            } else {
-                return numColumns - remainingKeys;
-            }
-        }
-
-        private int getOptimizedColumns(int numKeys, int maxColumns) {
-            int numColumns = Math.min(numKeys, maxColumns);
-            while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) {
-                numColumns--;
-            }
-            return numColumns;
-        }
-
-        public int getDefaultKeyCoordX() {
-            return mLeftKeys * mDefaultKeyWidth;
-        }
-
-        public int getX(int n, int row) {
-            final int x = getColumnPos(n) * mDefaultKeyWidth + getDefaultKeyCoordX();
-            if (isTopRow(row)) {
-                return x + mTopRowAdjustment * (mDefaultKeyWidth / 2);
-            }
-            return x;
-        }
-
-        public int getY(int row) {
-            return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding;
-        }
-
-        public int getRowFlags(int row) {
-            int rowFlags = 0;
-            if (row == 0) rowFlags |= Keyboard.EDGE_TOP;
-            if (isTopRow(row)) rowFlags |= Keyboard.EDGE_BOTTOM;
-            return rowFlags;
-        }
-
-        private boolean isTopRow(int rowCount) {
-            return rowCount == mNumRows - 1;
-        }
-    }
-
-    public MiniKeyboardBuilder(KeyboardView view, int xmlId, Key parentKey,
-            Keyboard parentKeyboard) {
-        super(view.getContext(), new MiniKeyboardParams());
-        load(parentKeyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
-
-        // HACK: Current mini keyboard design totally relies on the 9-patch padding about horizontal
-        // and vertical key spacing. To keep the visual of mini keyboard as is, these hacks are
-        // needed to keep having the same horizontal and vertical key spacing.
-        mParams.mHorizontalGap = 0;
-        mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
-        // TODO: When we have correctly padded key background 9-patch drawables for mini keyboard,
-        // revert the above hacks and uncomment the following lines.
-        //mParams.mHorizontalGap = parentKeyboard.mHorizontalGap;
-        //mParams.mVerticalGap = parentKeyboard.mVerticalGap;
-
-        mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
-        mPopupCharacters = parentKey.mPopupCharacters;
-
-        final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, mParams.mDefaultKeyWidth);
-        mParams.setParameters(
-                mPopupCharacters.length, parentKey.mMaxPopupColumn,
-                keyWidth, parentKeyboard.mDefaultRowHeight,
-                parentKey.mX + (mParams.mDefaultKeyWidth - keyWidth) / 2,
-                view.getMeasuredWidth());
-    }
-
-    private static int getMaxKeyWidth(KeyboardView view, CharSequence[] popupCharacters,
-            int minKeyWidth) {
-        Paint paint = null;
-        Rect bounds = null;
-        int maxWidth = 0;
-        for (CharSequence popupSpec : popupCharacters) {
-            final CharSequence label = PopupCharactersParser.getLabel(popupSpec.toString());
-            // If the label is single letter, minKeyWidth is enough to hold the label.
-            if (label != null && label.length() > 1) {
-                if (paint == null) {
-                    paint = new Paint();
-                    paint.setAntiAlias(true);
-                }
-                final int labelSize = view.getDefaultLabelSizeAndSetPaint(paint);
-                paint.setTextSize(labelSize);
-                if (bounds == null) bounds = new Rect();
-                paint.getTextBounds(label.toString(), 0, label.length(), bounds);
-                if (maxWidth < bounds.width())
-                    maxWidth = bounds.width();
-            }
-        }
-        final int horizontalPadding = (int)view.getContext().getResources().getDimension(
-                R.dimen.mini_keyboard_key_horizontal_padding);
-        return Math.max(minKeyWidth, maxWidth + horizontalPadding);
-    }
-
-    @Override
-    public MiniKeyboard build() {
-        final MiniKeyboardParams params = mParams;
-        for (int n = 0; n < mPopupCharacters.length; n++) {
-            final CharSequence label = mPopupCharacters[n];
-            final int row = n / params.mNumColumns;
-            final Key key = new Key(mResources, params, label, params.getX(n, row), params.getY(row),
-                    params.mDefaultKeyWidth, params.mDefaultRowHeight, params.getRowFlags(row));
-            params.onAddKey(key);
-        }
-        return new MiniKeyboard(params);
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
index 032489e..7c5abe3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
@@ -196,13 +196,6 @@
         }
     };
 
-    public static final CodeFilter NON_ASCII_FILTER = new CodeFilter() {
-        @Override
-        public boolean shouldFilterOut(int code) {
-            return code < 0x20 || code > 0x7e;
-        }
-    };
-
     public static CharSequence[] filterOut(Resources res, CharSequence[] popupCharacters,
             CodeFilter filter) {
         if (popupCharacters == null || popupCharacters.length < 1) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index ffd204d..9642151 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -64,24 +64,10 @@
             }
         }
 
-        // null == dictList is not supposed to be possible, but better safe than sorry and it's
-        // safer for future extension. In this case, rather than returning null, it should be safer
-        // to return an empty DictionaryCollection.
-        if (null == dictList) {
-            return new DictionaryCollection();
-        } else {
-            if (dictList.isEmpty()) {
-                // The list may be empty if no dictionaries have been added. The getter should not
-                // return an empty list, but if it does we end up here. Likewise, if the files
-                // we found could not be opened by the native code for any reason (format mismatch,
-                // file too big to fit in memory, etc) then we could have an empty list. In this
-                // case we want to fall back on the resource.
-                return new DictionaryCollection(createBinaryDictionary(context, fallbackResId,
-                        locale));
-            } else {
-                return new DictionaryCollection(dictList);
-            }
-        }
+        // If the list is empty, that means we should not use any dictionary (for example, the user
+        // explicitly disabled the main dictionary), so the following is okay. dictList is never
+        // null, but if for some reason it is, DictionaryCollection handles it gracefully.
+        return new DictionaryCollection(dictList);
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index afbdd36..394414d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -113,7 +113,7 @@
     // Key events coming any faster than this are long-presses.
     private static final int QUICK_PRESS = 200;
 
-    private static final int SCREEN_ORIENTATION_CHANGE_DETECTION_DELAY = 2;
+    private static final int START_INPUT_VIEW_DELAY_WHEN_SCREEN_ORIENTATION_STARTED = 10;
     private static final int ACCUMULATE_START_INPUT_VIEW_DELAY = 20;
     private static final int RESTORE_KEYBOARD_STATE_DELAY = 500;
 
@@ -198,8 +198,6 @@
 
     // Member variables for remembering the current device orientation.
     private int mDisplayOrientation;
-    private int mDisplayWidth;
-    private int mDisplayHeight;
 
     // Object for reacting to adding/removing a dictionary pack.
     private BroadcastReceiver mDictionaryPackInstallReceiver =
@@ -219,31 +217,10 @@
         private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5;
         private static final int MSG_SPACE_TYPED = 6;
         private static final int MSG_SET_BIGRAM_PREDICTIONS = 7;
-        private static final int MSG_CONFIRM_ORIENTATION_CHANGE = 8;
+        private static final int MSG_START_ORIENTATION_CHANGE = 8;
         private static final int MSG_START_INPUT_VIEW = 9;
         private static final int MSG_RESTORE_KEYBOARD_LAYOUT = 10;
 
-        private static class OrientationChangeArgs {
-            public final int mOldWidth;
-            public final int mOldHeight;
-            private int mRetryCount;
-
-            public OrientationChangeArgs(int oldw, int oldh) {
-                mOldWidth = oldw;
-                mOldHeight = oldh;
-                mRetryCount = 0;
-            }
-
-            public boolean hasTimedOut() {
-                mRetryCount++;
-                return mRetryCount >= 10;
-            }
-
-            public boolean hasOrientationChangeFinished(DisplayMetrics dm) {
-                return dm.widthPixels != mOldWidth && dm.heightPixels != mOldHeight;
-            }
-        }
-
         public UIHandler(LatinIME outerInstance) {
             super(outerInstance);
         }
@@ -291,18 +268,6 @@
                             (LatinKeyboard)msg.obj);
                 }
                 break;
-            case MSG_CONFIRM_ORIENTATION_CHANGE: {
-                final OrientationChangeArgs args = (OrientationChangeArgs)msg.obj;
-                final Resources res = latinIme.mResources;
-                final DisplayMetrics dm = res.getDisplayMetrics();
-                if (args.hasTimedOut() || args.hasOrientationChangeFinished(dm)) {
-                    latinIme.setDisplayGeometry(res.getConfiguration(), dm);
-                } else {
-                    // It seems orientation changing is on going.
-                    postConfirmOrientationChange(args);
-                }
-                break;
-            }
             case MSG_START_INPUT_VIEW:
                 latinIme.onStartInputView((EditorInfo)msg.obj, false);
                 break;
@@ -411,22 +376,16 @@
             }
         }
 
-        private void postConfirmOrientationChange(OrientationChangeArgs args) {
-            removeMessages(MSG_CONFIRM_ORIENTATION_CHANGE);
-            // Will confirm whether orientation change has finished or not again.
-            sendMessageDelayed(obtainMessage(MSG_CONFIRM_ORIENTATION_CHANGE, args),
-                    SCREEN_ORIENTATION_CHANGE_DETECTION_DELAY);
-        }
-
-        public void startOrientationChanging(int oldw, int oldh) {
-            postConfirmOrientationChange(new OrientationChangeArgs(oldw, oldh));
+        public void startOrientationChanging() {
+            sendMessageDelayed(obtainMessage(MSG_START_ORIENTATION_CHANGE),
+                    START_INPUT_VIEW_DELAY_WHEN_SCREEN_ORIENTATION_STARTED);
             final LatinIME latinIme = getOuterInstance();
             latinIme.mKeyboardSwitcher.getKeyboardState().save();
             postRestoreKeyboardLayout();
         }
 
         public boolean postStartInputView(EditorInfo attribute) {
-            if (hasMessages(MSG_CONFIRM_ORIENTATION_CHANGE) || hasMessages(MSG_START_INPUT_VIEW)) {
+            if (hasMessages(MSG_START_ORIENTATION_CHANGE) || hasMessages(MSG_START_INPUT_VIEW)) {
                 removeMessages(MSG_START_INPUT_VIEW);
                 // Postpone onStartInputView by ACCUMULATE_START_INPUT_VIEW_DELAY and see if
                 // orientation change has finished.
@@ -438,12 +397,6 @@
         }
     }
 
-    private void setDisplayGeometry(Configuration conf, DisplayMetrics metric) {
-        mDisplayOrientation = conf.orientation;
-        mDisplayWidth = metric.widthPixels;
-        mDisplayHeight = metric.heightPixels;
-    }
-
     @Override
     public void onCreate() {
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -481,7 +434,7 @@
             }
         }
 
-        setDisplayGeometry(res.getConfiguration(), res.getDisplayMetrics());
+        mDisplayOrientation = res.getConfiguration().orientation;
 
         // Register to receive ringer mode change and network state change.
         // Also receive installation and removal of a dictionary pack.
@@ -609,8 +562,9 @@
     public void onConfigurationChanged(Configuration conf) {
         mSubtypeSwitcher.onConfigurationChanged(conf);
         // If orientation changed while predicting, commit the change
-        if (conf.orientation != mDisplayOrientation) {
-            mHandler.startOrientationChanging(mDisplayWidth, mDisplayHeight);
+        if (mDisplayOrientation != conf.orientation) {
+            mDisplayOrientation = conf.orientation;
+            mHandler.startOrientationChanging();
             final InputConnection ic = getCurrentInputConnection();
             commitTyped(ic);
             if (ic != null) ic.finishComposingText(); // For voice input
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilderTests.java b/tests/src/com/android/inputmethod/keyboard/MiniKeyboardBuilderTests.java
similarity index 99%
rename from tests/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilderTests.java
rename to tests/src/com/android/inputmethod/keyboard/MiniKeyboardBuilderTests.java
index 1c5661b..a143bba 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilderTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/MiniKeyboardBuilderTests.java
@@ -14,9 +14,9 @@
  * the License.
  */
 
-package com.android.inputmethod.keyboard.internal;
+package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder.MiniKeyboardParams;
+import com.android.inputmethod.keyboard.MiniKeyboard.Builder.MiniKeyboardParams;
 
 import android.test.AndroidTestCase;
 
