diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 9b7937618178ab46a63636ed33b2411efbf9d937..c268abb8946af84acec927f07be75ecc09569d77 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -35,47 +35,47 @@ public class Key {
      * All the key codes (unicode or custom code) that this key could generate, zero'th
      * being the most important.
      */
-    public int[] codes;
+    public int[] mCodes;
     /** The unicode that this key generates in manual temporary upper case mode. */
-    public int manualTemporaryUpperCaseCode;
+    public int mManualTemporaryUpperCaseCode;
 
     /** Label to display */
-    public CharSequence label;
+    public CharSequence mLabel;
     /** Option of the label */
-    public int labelOption;
+    public int mLabelOption;
 
     /** Icon to display instead of a label. Icon takes precedence over a label */
-    public Drawable icon;
+    public Drawable mIcon;
     /** Hint icon to display on the key in conjunction with the label */
-    public Drawable hintIcon;
+    public Drawable mHintIcon;
     /** Preview version of the icon, for the preview popup */
     /**
      * The hint icon to display on the key when keyboard is in manual temporary upper case
      * mode.
      */
-    public Drawable manualTemporaryUpperCaseHintIcon;
+    public Drawable mManualTemporaryUpperCaseHintIcon;
 
-    public Drawable iconPreview;
+    public Drawable mPreviewIcon;
     /** Width of the key, not including the gap */
-    public int width;
+    public int mWidth;
     /** Height of the key, not including the gap */
-    public int height;
+    public int mHeight;
     /** The horizontal gap before this key */
-    public int gap;
+    public int mGap;
     /** Whether this key is sticky, i.e., a toggle key */
-    public boolean sticky;
+    public boolean mSticky;
     /** X coordinate of the key in the keyboard layout */
-    public int x;
+    public int mX;
     /** Y coordinate of the key in the keyboard layout */
-    public int y;
+    public int mY;
     /** The current pressed state of this key */
-    public boolean pressed;
+    public boolean mPressed;
     /** If this is a sticky key, is it on? */
-    public boolean on;
+    public boolean mOn;
     /** Text to output when pressed. This can be multiple characters, like ".com" */
-    public CharSequence text;
+    public CharSequence mOutputText;
     /** Popup characters */
-    public CharSequence popupCharacters;
+    public CharSequence mPopupCharacters;
 
     /**
      * Flags that specify the anchoring to edges of the keyboard for detecting touch events
@@ -83,18 +83,18 @@ public class Key {
      * {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT},
      * {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}.
      */
-    public int edgeFlags;
+    public int mEdgeFlags;
     /** Whether this is a modifier key, such as Shift or Alt */
-    public boolean modifier;
+    public boolean mModifier;
     /** The Keyboard that this key belongs to */
-    protected final Keyboard keyboard;
+    protected final Keyboard mKeyboard;
     /**
      * If this key pops up a mini keyboard, this is the resource id for the XML layout for that
      * keyboard.
      */
-    public int popupResId;
+    public int mPopupResId;
     /** Whether this key repeats itself when held down */
-    public boolean repeatable;
+    public boolean mRepeatable;
 
 
     private final static int[] KEY_STATE_NORMAL_ON = {
@@ -124,13 +124,24 @@ public class Key {
         android.R.attr.state_pressed
     };
 
+    // functional normal state (with properties)
+    private static final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
+            android.R.attr.state_single
+    };
+
+    // functional pressed state (with properties)
+    private static final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
+            android.R.attr.state_single,
+            android.R.attr.state_pressed
+    };
+
     /** Create an empty key with no attributes. */
     public Key(Row parent) {
-        keyboard = parent.parent;
-        height = parent.defaultHeight;
-        gap = parent.defaultHorizontalGap;
-        width = parent.defaultWidth - gap;
-        edgeFlags = parent.rowEdgeFlags;
+        mKeyboard = parent.mParent;
+        mHeight = parent.mDefaultHeight;
+        mGap = parent.mDefaultHorizontalGap;
+        mWidth = parent.mDefaultWidth - mGap;
+        mEdgeFlags = parent.mRowEdgeFlags;
     }
 
     /** Create a key with the given top-left coordinate and extract its attributes from
@@ -148,15 +159,15 @@ public class Key {
 
         TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard);
-        height = KeyboardParser.getDimensionOrFraction(a,
+        mHeight = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_keyHeight,
-                keyboard.mDisplayHeight, parent.defaultHeight);
-        gap = KeyboardParser.getDimensionOrFraction(a,
+                mKeyboard.mDisplayHeight, parent.mDefaultHeight);
+        mGap = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_horizontalGap,
-                keyboard.mDisplayWidth, parent.defaultHorizontalGap);
-        width = KeyboardParser.getDimensionOrFraction(a,
+                mKeyboard.mDisplayWidth, parent.mDefaultHorizontalGap);
+        mWidth = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_keyWidth,
-                keyboard.mDisplayWidth, parent.defaultWidth) - gap;
+                mKeyboard.mDisplayWidth, parent.mDefaultWidth) - mGap;
         a.recycle();
 
         a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key);
@@ -172,42 +183,48 @@ public class Key {
         }
 
         // Horizontal gap is divided equally to both sides of the key.
-        this.x = x + gap / 2;
-        this.y = y;
-
-        codes = style.getIntArray(a, R.styleable.Keyboard_Key_codes);
-        iconPreview = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview);
-        Keyboard.setDefaultBounds(iconPreview);
-        popupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters);
-        popupResId = style.getResourceId(a, R.styleable.Keyboard_Key_popupKeyboard, 0);
-        repeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false);
-        modifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false);
-        sticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false);
-        edgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0);
-        edgeFlags |= parent.rowEdgeFlags;
-
-        icon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon);
-        Keyboard.setDefaultBounds(icon);
-        hintIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyHintIcon);
-        Keyboard.setDefaultBounds(hintIcon);
-        manualTemporaryUpperCaseHintIcon = style.getDrawable(a,
+        this.mX = x + mGap / 2;
+        this.mY = y;
+
+        mCodes = style.getIntArray(a, R.styleable.Keyboard_Key_codes);
+        mPreviewIcon = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview);
+        Keyboard.setDefaultBounds(mPreviewIcon);
+        mPopupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters);
+        mPopupResId = style.getResourceId(a, R.styleable.Keyboard_Key_popupKeyboard, 0);
+        mRepeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false);
+        mModifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false);
+        mSticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false);
+        mEdgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0);
+        mEdgeFlags |= parent.mRowEdgeFlags;
+
+        mIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon);
+        Keyboard.setDefaultBounds(mIcon);
+        mHintIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyHintIcon);
+        Keyboard.setDefaultBounds(mHintIcon);
+        mManualTemporaryUpperCaseHintIcon = style.getDrawable(a,
                 R.styleable.Keyboard_Key_manualTemporaryUpperCaseHintIcon);
-        Keyboard.setDefaultBounds(manualTemporaryUpperCaseHintIcon);
+        Keyboard.setDefaultBounds(mManualTemporaryUpperCaseHintIcon);
 
-        label = style.getText(a, R.styleable.Keyboard_Key_keyLabel);
-        labelOption = style.getFlag(a, R.styleable.Keyboard_Key_keyLabelOption, 0);
-        manualTemporaryUpperCaseCode = style.getInt(a,
+        mLabel = style.getText(a, R.styleable.Keyboard_Key_keyLabel);
+        mLabelOption = style.getFlag(a, R.styleable.Keyboard_Key_keyLabelOption, 0);
+        mManualTemporaryUpperCaseCode = style.getInt(a,
                 R.styleable.Keyboard_Key_manualTemporaryUpperCaseCode, 0);
-        text = style.getText(a, R.styleable.Keyboard_Key_keyOutputText);
+        mOutputText = style.getText(a, R.styleable.Keyboard_Key_keyOutputText);
         final Drawable shiftedIcon = style.getDrawable(a,
                 R.styleable.Keyboard_Key_shiftedIcon);
+        a.recycle();
+
         if (shiftedIcon != null)
-            keyboard.getShiftedIcons().put(this, shiftedIcon);
+            mKeyboard.getShiftedIcons().put(this, shiftedIcon);
 
-        if (codes == null && !TextUtils.isEmpty(label)) {
-            codes = new int[] { label.charAt(0) };
+        if (mCodes == null && !TextUtils.isEmpty(mLabel)) {
+            mCodes = new int[] { mLabel.charAt(0) };
+        }
+
+        if (mPopupCharacters == null || mPopupCharacters.length() == 0) {
+            // If there is a keyboard with no keys specified in popupCharacters
+            mPopupResId = 0;
         }
-        a.recycle();
     }
 
     /**
@@ -216,7 +233,7 @@ public class Key {
      * @see #onReleased(boolean)
      */
     public void onPressed() {
-        pressed = !pressed;
+        mPressed = !mPressed;
     }
 
     /**
@@ -226,10 +243,9 @@ public class Key {
      * @see #onPressed()
      */
     public void onReleased(boolean inside) {
-        pressed = !pressed;
-        if (sticky) {
-            on = !on;
-        }
+        mPressed = !mPressed;
+        if (mSticky && !mKeyboard.isShiftLockEnabled(this))
+            mOn = !mOn;
     }
 
     /**
@@ -241,14 +257,14 @@ public class Key {
      * inside the key.
      */
     public boolean isInside(int x, int y) {
-        boolean leftEdge = (edgeFlags & Keyboard.EDGE_LEFT) > 0;
-        boolean rightEdge = (edgeFlags & Keyboard.EDGE_RIGHT) > 0;
-        boolean topEdge = (edgeFlags & Keyboard.EDGE_TOP) > 0;
-        boolean bottomEdge = (edgeFlags & Keyboard.EDGE_BOTTOM) > 0;
-        if ((x >= this.x || (leftEdge && x <= this.x + this.width))
-                && (x < this.x + this.width || (rightEdge && x >= this.x))
-                && (y >= this.y || (topEdge && y <= this.y + this.height))
-                && (y < this.y + this.height || (bottomEdge && y >= this.y))) {
+        boolean leftEdge = (mEdgeFlags & Keyboard.EDGE_LEFT) > 0;
+        boolean rightEdge = (mEdgeFlags & Keyboard.EDGE_RIGHT) > 0;
+        boolean topEdge = (mEdgeFlags & Keyboard.EDGE_TOP) > 0;
+        boolean bottomEdge = (mEdgeFlags & Keyboard.EDGE_BOTTOM) > 0;
+        if ((x >= this.mX || (leftEdge && x <= this.mX + this.mWidth))
+                && (x < this.mX + this.mWidth || (rightEdge && x >= this.mX))
+                && (y >= this.mY || (topEdge && y <= this.mY + this.mHeight))
+                && (y < this.mY + this.mHeight || (bottomEdge && y >= this.mY))) {
             return true;
         } else {
             return false;
@@ -262,10 +278,10 @@ public class Key {
      * @return the square of the distance of the point from the nearest edge of the key
      */
     public int squaredDistanceToEdge(int x, int y) {
-        final int left = this.x;
-        final int right = left + this.width;
-        final int top = this.y;
-        final int bottom = top + this.height;
+        final int left = this.mX;
+        final int right = left + this.mWidth;
+        final int top = this.mY;
+        final int bottom = top + this.mHeight;
         final int edgeX = x < left ? left : (x > right ? right : x);
         final int edgeY = y < top ? top : (y > bottom ? bottom : y);
         final int dx = x - edgeX;
@@ -273,29 +289,43 @@ public class Key {
         return dx * dx + dy * dy;
     }
 
+    // sticky is used for shift key.  If a key is not sticky and is modifier,
+    // the key will be treated as functional.
+    private boolean isFunctionalKey() {
+        return !mSticky && mModifier;
+    }
+
     /**
      * Returns the drawable state for the key, based on the current state and type of the key.
      * @return the drawable state of the key.
      * @see android.graphics.drawable.StateListDrawable#setState(int[])
      */
     public int[] getCurrentDrawableState() {
+        if (isFunctionalKey()) {
+            if (mPressed) {
+                return KEY_STATE_FUNCTIONAL_PRESSED;
+            } else {
+                return KEY_STATE_FUNCTIONAL_NORMAL;
+            }
+        }
+
         int[] states = KEY_STATE_NORMAL;
 
-        if (on) {
-            if (pressed) {
+        if (mOn) {
+            if (mPressed) {
                 states = KEY_STATE_PRESSED_ON;
             } else {
                 states = KEY_STATE_NORMAL_ON;
             }
         } else {
-            if (sticky) {
-                if (pressed) {
+            if (mSticky) {
+                if (mPressed) {
                     states = KEY_STATE_PRESSED_OFF;
                 } else {
                     states = KEY_STATE_NORMAL_OFF;
                 }
             } else {
-                if (pressed) {
+                if (mPressed) {
                     states = KEY_STATE_PRESSED;
                 }
             }
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index b7541557990e9abc1f410907c928984f672a3c15..869d130679a496f480a28554412093963b96963a 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -29,6 +29,7 @@ import android.util.Log;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -51,20 +52,32 @@ import java.util.Map;
  * </pre>
  */
 public class Keyboard {
-
-    static final String TAG = "Keyboard";
+    private static final String TAG = "Keyboard";
 
     public static final int EDGE_LEFT = 0x01;
     public static final int EDGE_RIGHT = 0x02;
     public static final int EDGE_TOP = 0x04;
     public static final int EDGE_BOTTOM = 0x08;
 
-    public static final int KEYCODE_SHIFT = -1;
-    public static final int KEYCODE_MODE_CHANGE = -2;
-    public static final int KEYCODE_CANCEL = -3;
-    public static final int KEYCODE_DONE = -4;
-    public static final int KEYCODE_DELETE = -5;
-    public static final int KEYCODE_ALT = -6;
+    public static final int CODE_ENTER = '\n';
+    public static final int CODE_TAB = '\t';
+    public static final int CODE_SPACE = ' ';
+    public static final int CODE_PERIOD = '.';
+
+    public static final int CODE_SHIFT = -1;
+    public static final int CODE_MODE_CHANGE = -2;
+    public static final int CODE_CANCEL = -3;
+    public static final int CODE_DONE = -4;
+    public static final int CODE_DELETE = -5;
+    public static final int CODE_ALT = -6;
+
+    public static final int CODE_OPTIONS = -100;
+    public static final int CODE_OPTIONS_LONGPRESS = -101;
+    public static final int CODE_CAPSLOCK = -103;
+    public static final int CODE_NEXT_LANGUAGE = -104;
+    public static final int CODE_PREV_LANGUAGE = -105;
+    // TODO: remove this once LatinIME stops referring to this.
+    public static final int CODE_VOICE = -109;
 
     /** Horizontal gap default for all rows */
     int mDefaultHorizontalGap;
@@ -78,14 +91,17 @@ public class Keyboard {
     /** Default gap between rows */
     int mDefaultVerticalGap;
 
-    /** Is the keyboard in the shifted state */
-    private boolean mShifted;
-
-    /** List of shift keys in this keyboard */
+    /** List of shift keys in this keyboard and its icons and state */
     private final List<Key> mShiftKeys = new ArrayList<Key>();
-
-    /** List of shift keys and its shifted state icon */
     private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
+    private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
+    private final HashSet<Key> mShiftLockEnabled = new HashSet<Key>();
+    private final KeyboardShiftState mShiftState = new KeyboardShiftState();
+
+    /** Space key and its icons */
+    protected Key mSpaceKey;
+    protected Drawable mSpaceIcon;
+    protected Drawable mSpacePreviewIcon;
 
     /** Total height of the keyboard, including the padding and keys */
     private int mTotalHeight;
@@ -191,11 +207,11 @@ public class Keyboard {
         mTotalWidth = 0;
 
         Row row = new Row(this);
-        row.defaultHeight = mDefaultHeight;
-        row.defaultWidth = mDefaultWidth;
-        row.defaultHorizontalGap = mDefaultHorizontalGap;
-        row.verticalGap = mDefaultVerticalGap;
-        row.rowEdgeFlags = EDGE_TOP | EDGE_BOTTOM;
+        row.mDefaultHeight = mDefaultHeight;
+        row.mDefaultWidth = mDefaultWidth;
+        row.mDefaultHorizontalGap = mDefaultHorizontalGap;
+        row.mVerticalGap = mDefaultVerticalGap;
+        row.mRowEdgeFlags = EDGE_TOP | EDGE_BOTTOM;
         final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns;
         for (int i = 0; i < characters.length(); i++) {
             char c = characters.charAt(i);
@@ -207,12 +223,12 @@ public class Keyboard {
             }
             final Key key = new Key(row);
             // Horizontal gap is divided equally to both sides of the key.
-            key.x = x + key.gap / 2;
-            key.y = y;
-            key.label = String.valueOf(c);
-            key.codes = new int[] { c };
+            key.mX = x + key.mGap / 2;
+            key.mY = y;
+            key.mLabel = String.valueOf(c);
+            key.mCodes = new int[] { c };
             column++;
-            x += key.width + key.gap;
+            x += key.mWidth + key.mGap;
             mKeys.add(key);
             if (x > mTotalWidth) {
                 mTotalWidth = x;
@@ -283,27 +299,88 @@ public class Keyboard {
         return mDisplayWidth;
     }
 
-    public boolean setShifted(boolean shiftState) {
-        for (final Key key : mShiftKeys) {
-            key.on = shiftState;
+    public List<Key> getShiftKeys() {
+        return mShiftKeys;
+    }
+
+    public Map<Key, Drawable> getShiftedIcons() {
+        return mShiftedIcons;
+    }
+
+    public void enableShiftLock() {
+        for (final Key key : getShiftKeys()) {
+            mShiftLockEnabled.add(key);
+            mNormalShiftIcons.put(key, key.mIcon);
         }
-        if (mShifted != shiftState) {
-            mShifted = shiftState;
-            return true;
+    }
+
+    public boolean isShiftLockEnabled(Key key) {
+        return mShiftLockEnabled.contains(key);
+    }
+
+    public boolean setShiftLocked(boolean newShiftLockState) {
+        final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
+        for (final Key key : getShiftKeys()) {
+            key.mOn = newShiftLockState;
+            key.mIcon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key);
+        }
+        mShiftState.setShiftLocked(newShiftLockState);
+        return true;
+    }
+
+    public boolean isShiftLocked() {
+        return mShiftState.isShiftLocked();
+    }
+
+    public boolean setShifted(boolean newShiftState) {
+        final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
+        for (final Key key : getShiftKeys()) {
+            if (!newShiftState && !mShiftState.isShiftLocked()) {
+                key.mIcon = mNormalShiftIcons.get(key);
+            } else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
+                key.mIcon = shiftedIcons.get(key);
+            }
         }
-        return false;
+        return mShiftState.setShifted(newShiftState);
     }
 
     public boolean isShiftedOrShiftLocked() {
-        return mShifted;
+        return mShiftState.isShiftedOrShiftLocked();
     }
 
-    public List<Key> getShiftKeys() {
-        return mShiftKeys;
+    public void setAutomaticTemporaryUpperCase() {
+        setShifted(true);
+        mShiftState.setAutomaticTemporaryUpperCase();
     }
 
-    public Map<Key, Drawable> getShiftedIcons() {
-        return mShiftedIcons;
+    public boolean isAutomaticTemporaryUpperCase() {
+        return isAlphaKeyboard() && mShiftState.isAutomaticTemporaryUpperCase();
+    }
+
+    public boolean isManualTemporaryUpperCase() {
+        return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
+    }
+
+    public KeyboardShiftState getKeyboardShiftState() {
+        return mShiftState;
+    }
+
+    public boolean isAlphaKeyboard() {
+        return mId.isAlphabetKeyboard();
+    }
+
+    public boolean isPhoneKeyboard() {
+        return mId.isPhoneKeyboard();
+    }
+
+    public boolean isNumberKeyboard() {
+        return mId.isNumberKeyboard();
+    }
+
+    public void setSpaceKey(Key space) {
+        mSpaceKey = space;
+        mSpaceIcon = space.mIcon;
+        mSpacePreviewIcon = space.mPreviewIcon;
     }
 
     private void computeNearestNeighbors() {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 289e4c0e815d56c5a34213a2a691e182f7fb949c..883d2175c71491f6385fec80cb88b1b7faf97fdb 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -83,10 +83,18 @@ public class KeyboardId {
         return mXmlId;
     }
 
-    public boolean isAlphabetMode() {
+    public boolean isAlphabetKeyboard() {
         return mXmlId == R.xml.kbd_qwerty;
     }
 
+    public boolean isPhoneKeyboard() {
+        return mMode == MODE_PHONE;
+    }
+
+    public boolean isNumberKeyboard() {
+        return mMode == MODE_NUMBER;
+    }
+
     @Override
     public boolean equals(Object other) {
         return other instanceof KeyboardId && equals((KeyboardId) other);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 2147ee2891e3ea20fee282114860b887fce66082..dd80f0ed01a5a7e449257a8918c7fd04533442ac 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -264,8 +264,10 @@ public class KeyboardParser {
                     mKeyStyles);
             checkEndTag(TAG_KEY, parser);
             keys.add(key);
-            if (key.codes[0] == Keyboard.KEYCODE_SHIFT)
+            if (key.mCodes[0] == Keyboard.CODE_SHIFT)
                 mKeyboard.getShiftKeys().add(key);
+            if (key.mCodes[0] == Keyboard.CODE_SPACE)
+                mKeyboard.setSpaceKey(key);
             endKey(key);
         }
     }
@@ -492,12 +494,12 @@ public class KeyboardParser {
     private void endRow() {
         if (mCurrentRow == null)
             throw new InflateException("orphant end row tag");
-        mCurrentY += mCurrentRow.verticalGap + mCurrentRow.defaultHeight;
+        mCurrentY += mCurrentRow.mVerticalGap + mCurrentRow.mDefaultHeight;
         mCurrentRow = null;
     }
 
     private void endKey(Key key) {
-        mCurrentX += key.gap + key.width;
+        mCurrentX += key.mGap + key.mWidth;
         if (mCurrentX > mMaxRowWidth)
             mMaxRowWidth = mCurrentX;
     }
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
similarity index 95%
rename from java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java
rename to java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
index 6d78428570bb04fa3a8b62c1adcc9918877ac8e4..3e1eaf44eb2add1743b85fabd1a928139c78c97f 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
@@ -16,12 +16,10 @@
 
 package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.latin.KeyboardSwitcher;
-
 import android.util.Log;
 
-public class LatinKeyboardShiftState {
-    private static final String TAG = "LatinKeyboardShiftState";
+public class KeyboardShiftState {
+    private static final String TAG = "KeyboardShiftState";
     private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
 
     private static final int NORMAL = 0;
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
similarity index 97%
rename from java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
rename to java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index e8487e798aeaa4b2a2f9fe339038a658963d78a8..d3302fd6f1e2d4586f2532c18fa7d112889d54fc 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2008 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
@@ -14,12 +14,14 @@
  * the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.keyboard.LatinKeyboard;
-import com.android.inputmethod.keyboard.LatinKeyboardView;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinIMESettings;
+import com.android.inputmethod.latin.LatinIMEUtil;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
 
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -238,7 +240,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
     }
 
     public boolean isAlphabetMode() {
-        return mCurrentId != null && mCurrentId.isAlphabetMode();
+        return mCurrentId != null && mCurrentId.isAlphabetKeyboard();
     }
 
     public boolean isInputViewShown() {
@@ -530,12 +532,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
         // characters followed by a space/enter
         switch (mSymbolsModeState) {
         case SYMBOLS_MODE_STATE_BEGIN:
-            if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) {
+            if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key > 0) {
                 mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
             }
             break;
         case SYMBOLS_MODE_STATE_SYMBOL:
-            if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) {
+            if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
                 changeKeyboardMode();
             }
             break;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index ae6d097169e2304a3113aaa7ffdd47c569169e01..5fecb30009087055091dac39d4c4bdcb37f6f69b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -58,8 +58,6 @@ import java.util.WeakHashMap;
  * A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key
  * presses and touch movements.
  *
- * TODO: References to LatinKeyboard in this class should be replaced with ones to its base class.
- *
  * @attr ref R.styleable#KeyboardView_keyBackground
  * @attr ref R.styleable#KeyboardView_keyPreviewLayout
  * @attr ref R.styleable#KeyboardView_keyPreviewOffset
@@ -592,7 +590,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         int maxCount = 0;
         int mostCommonWidth = 0;
         for (Key key : keys) {
-            final Integer width = key.width + key.gap;
+            final Integer width = key.mWidth + key.mGap;
             Integer count = histogram.get(width);
             if (count == null)
                 count = 0;
@@ -648,17 +646,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         final int kbdPaddingTop = getPaddingTop();
         final Key[] keys = mKeys;
         final Key invalidKey = mInvalidatedKey;
-        final boolean isManualTemporaryUpperCase = (mKeyboard instanceof LatinKeyboard
-                && ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase());
+        final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
 
         boolean drawSingleKey = false;
         if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
             // TODO we should use Rect.inset and Rect.contains here.
             // Is clipRegion completely contained within the invalidated key?
-            if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left &&
-                    invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top &&
-                    invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right &&
-                    invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) {
+            if (invalidKey.mX + kbdPaddingLeft - 1 <= clipRegion.left &&
+                    invalidKey.mY + kbdPaddingTop - 1 <= clipRegion.top &&
+                    invalidKey.mX + invalidKey.mWidth + kbdPaddingLeft + 1 >= clipRegion.right &&
+                    invalidKey.mY + invalidKey.mHeight + kbdPaddingTop + 1 >= clipRegion.bottom) {
                 drawSingleKey = true;
             }
         }
@@ -673,16 +670,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             keyBackground.setState(drawableState);
 
             // Switch the character to uppercase if shift is pressed
-            String label = key.label == null? null : adjustCase(key.label).toString();
+            String label = key.mLabel == null? null : adjustCase(key.mLabel).toString();
 
             final Rect bounds = keyBackground.getBounds();
-            if (key.width != bounds.right || key.height != bounds.bottom) {
-                keyBackground.setBounds(0, 0, key.width, key.height);
+            if (key.mWidth != bounds.right || key.mHeight != bounds.bottom) {
+                keyBackground.setBounds(0, 0, key.mWidth, key.mHeight);
             }
-            canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop);
+            canvas.translate(key.mX + kbdPaddingLeft, key.mY + kbdPaddingTop);
             keyBackground.draw(canvas);
 
-            final int rowHeight = padding.top + key.height;
+            final int rowHeight = padding.top + key.mHeight;
             // Draw key label
             if (label != null) {
                 // For characters, use large font. For labels like "Done", use small font.
@@ -691,36 +688,36 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
 
                 // Vertical label text alignment.
                 final float baseline;
-                if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) {
-                    baseline = key.height -
+                if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) {
+                    baseline = key.mHeight -
                             + labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR;
                     if (DEBUG_SHOW_ALIGN)
-                        drawHorizontalLine(canvas, (int)baseline, key.width, 0xc0008000,
+                        drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000,
                                 new Paint());
                 } else { // Align center
-                    final float centerY = (key.height + padding.top - padding.bottom) / 2;
+                    final float centerY = (key.mHeight + padding.top - padding.bottom) / 2;
                     baseline = centerY
                             + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER;
                 }
                 // Horizontal label text alignment
                 final int positionX;
-                if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
+                if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
                     positionX = mKeyLabelHorizontalPadding + padding.left;
                     paint.setTextAlign(Align.LEFT);
                     if (DEBUG_SHOW_ALIGN)
                         drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint());
-                } else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
-                    positionX = key.width - mKeyLabelHorizontalPadding - padding.right;
+                } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
+                    positionX = key.mWidth - mKeyLabelHorizontalPadding - padding.right;
                     paint.setTextAlign(Align.RIGHT);
                     if (DEBUG_SHOW_ALIGN)
                         drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint());
                 } else {
-                    positionX = (key.width + padding.left - padding.right) / 2;
+                    positionX = (key.mWidth + padding.left - padding.right) / 2;
                     paint.setTextAlign(Align.CENTER);
                     if (DEBUG_SHOW_ALIGN && label.length() > 1)
                         drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
                 }
-                if (key.manualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
+                if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
                     paint.setColor(mKeyTextColorDisabled);
                 } else {
                     paint.setColor(mKeyTextColor);
@@ -732,47 +729,47 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
                 paint.setShadowLayer(0, 0, 0, 0);
             }
             // Draw key icon
-            if (key.label == null && key.icon != null) {
-                final int drawableWidth = key.icon.getIntrinsicWidth();
-                final int drawableHeight = key.icon.getIntrinsicHeight();
+            if (key.mLabel == null && key.mIcon != null) {
+                final int drawableWidth = key.mIcon.getIntrinsicWidth();
+                final int drawableHeight = key.mIcon.getIntrinsicHeight();
                 final int drawableX;
                 final int drawableY = (
-                        key.height + padding.top - padding.bottom - drawableHeight) / 2;
-                if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
+                        key.mHeight + padding.top - padding.bottom - drawableHeight) / 2;
+                if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
                     drawableX = padding.left + mKeyLabelHorizontalPadding;
                     if (DEBUG_SHOW_ALIGN)
                         drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint());
-                } else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
-                    drawableX = key.width - padding.right - mKeyLabelHorizontalPadding
+                } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
+                    drawableX = key.mWidth - padding.right - mKeyLabelHorizontalPadding
                             - drawableWidth;
                     if (DEBUG_SHOW_ALIGN)
                         drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight,
                                 0xc0808000, new Paint());
                 } else { // Align center
-                    drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2;
+                    drawableX = (key.mWidth + padding.left - padding.right - drawableWidth) / 2;
                     if (DEBUG_SHOW_ALIGN)
                         drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight,
                                 0xc0008080, new Paint());
                 }
-                drawIcon(canvas, key.icon, drawableX, drawableY, drawableWidth, drawableHeight);
+                drawIcon(canvas, key.mIcon, drawableX, drawableY, drawableWidth, drawableHeight);
                 if (DEBUG_SHOW_ALIGN)
                     drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
                             0x80c00000, new Paint());
             }
-            if (key.hintIcon != null) {
-                final int drawableWidth = key.width;
-                final int drawableHeight = key.height;
+            if (key.mHintIcon != null) {
+                final int drawableWidth = key.mWidth;
+                final int drawableHeight = key.mHeight;
                 final int drawableX = 0;
                 final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
                 Drawable icon = (isManualTemporaryUpperCase
-                        && key.manualTemporaryUpperCaseHintIcon != null)
-                        ? key.manualTemporaryUpperCaseHintIcon : key.hintIcon;
+                        && key.mManualTemporaryUpperCaseHintIcon != null)
+                        ? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon;
                 drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
                 if (DEBUG_SHOW_ALIGN)
                     drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
                             0x80c0c000, new Paint());
             }
-            canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop);
+            canvas.translate(-key.mX - kbdPaddingLeft, -key.mY - kbdPaddingTop);
         }
 
         if (DEBUG_KEYBOARD_GRID) {
@@ -822,9 +819,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         // For characters, use large font. For labels like "Done", use small font.
         final int labelSize;
         final Typeface labelStyle;
-        if (label.length() > 1 && key.codes.length < 2) {
+        if (label.length() > 1 && key.mCodes.length < 2) {
             labelSize = mLabelTextSize;
-            if ((key.labelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) {
+            if ((key.mLabelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) {
                 labelStyle = Typeface.DEFAULT;
             } else {
                 labelStyle = Typeface.DEFAULT_BOLD;
@@ -927,11 +924,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         if (key == null || !mInForeground)
             return;
         // What we show as preview should match what we show on key top in onBufferDraw(). 
-        if (key.label != null) {
+        if (key.mLabel != null) {
             // TODO Should take care of temporaryShiftLabel here.
             mPreviewText.setCompoundDrawables(null, null, null, null);
             mPreviewText.setText(adjustCase(tracker.getPreviewText(key)));
-            if (key.label.length() > 1 && key.codes.length < 2) {
+            if (key.mLabel.length() > 1 && key.mCodes.length < 2) {
                 mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
                 mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
             } else {
@@ -940,12 +937,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             }
         } else {
             mPreviewText.setCompoundDrawables(null, null, null,
-                    key.iconPreview != null ? key.iconPreview : key.icon);
+                    key.mPreviewIcon != null ? key.mPreviewIcon : key.mIcon);
             mPreviewText.setText(null);
         }
         mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                 MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-        int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width
+        int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.mWidth
                 + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
         final int popupHeight = mPreviewHeight;
         LayoutParams lp = mPreviewText.getLayoutParams();
@@ -954,8 +951,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             lp.height = popupHeight;
         }
 
-        int popupPreviewX = key.x - (popupWidth - key.width) / 2;
-        int popupPreviewY = key.y - popupHeight + mPreviewOffset;
+        int popupPreviewX = key.mX - (popupWidth - key.mWidth) / 2;
+        int popupPreviewY = key.mY - popupHeight + mPreviewOffset;
 
         mHandler.cancelDismissPreview();
         if (mOffsetInWindow == null) {
@@ -969,7 +966,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         }
         // Set the preview background state
         mPreviewText.getBackground().setState(
-                key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
+                key.mPopupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
         popupPreviewX += mOffsetInWindow[0];
         popupPreviewY += mOffsetInWindow[1];
 
@@ -977,10 +974,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         if (popupPreviewY + mWindowY < 0) {
             // If the key you're pressing is on the left side of the keyboard, show the popup on
             // the right, offset by enough to see at least one key to the left/right.
-            if (key.x + key.width <= getWidth() / 2) {
-                popupPreviewX += (int) (key.width * 2.5);
+            if (key.mX + key.mWidth <= getWidth() / 2) {
+                popupPreviewX += (int) (key.mWidth * 2.5);
             } else {
-                popupPreviewX -= (int) (key.width * 2.5);
+                popupPreviewX -= (int) (key.mWidth * 2.5);
             }
             popupPreviewY += popupHeight;
         }
@@ -1028,11 +1025,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
             return;
         mInvalidatedKey = key;
         // TODO we should clean up this and record key's region to use in onBufferDraw.
-        mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(),
-                key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
+        mDirtyRect.union(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
+                key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
         onBufferDraw();
-        invalidate(key.x + getPaddingLeft(), key.y + getPaddingTop(),
-                key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
+        invalidate(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
+                key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
     }
 
     private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
@@ -1058,11 +1055,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
     private void onLongPressShiftKey(PointerTracker tracker) {
         tracker.setAlreadyProcessed();
         mPointerQueue.remove(tracker);
-        mKeyboardActionListener.onKey(LatinKeyboard.KEYCODE_CAPSLOCK, null, 0, 0);
+        mKeyboardActionListener.onKey(Keyboard.CODE_CAPSLOCK, null, 0, 0);
     }
 
     private View inflateMiniKeyboardContainer(Key popupKey) {
-        int popupKeyboardId = popupKey.popupResId;
+        int popupKeyboardId = popupKey.mPopupResId;
         LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         View container = inflater.inflate(mPopupLayout, null);
@@ -1116,8 +1113,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         miniKeyboard.mGestureDetector = null;
 
         Keyboard keyboard;
-        if (popupKey.popupCharacters != null) {
-            keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.popupCharacters,
+        if (popupKey.mPopupCharacters != null) {
+            keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.mPopupCharacters,
                     -1, getPaddingLeft() + getPaddingRight());
         } else {
             keyboard = new Keyboard(getContext(), popupKeyboardId);
@@ -1133,7 +1130,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
 
     private static boolean isOneRowKeys(List<Key> keys) {
         if (keys.size() == 0) return false;
-        final int edgeFlags = keys.get(0).edgeFlags;
+        final int edgeFlags = keys.get(0).mEdgeFlags;
         // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows,
         // does not have both top and bottom edge flags on at the same time.  On the other hand,
         // the first key of mini keyboard that was created with popupCharacters must have both top
@@ -1155,7 +1152,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         // TODO if popupKey.popupCharacters has only one letter, send it as key without opening
         // mini keyboard.
 
-        if (popupKey.popupResId == 0)
+        if (popupKey.mPopupResId == 0)
             return false;
 
         View container = mMiniKeyboardCache.get(popupKey);
@@ -1177,22 +1174,22 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         //  b) When we have the rightmost key in popup keyboard directly above the pressed key
         //     Left edges of both keys should be aligned for consistent default selection
         final List<Key> miniKeys = mMiniKeyboard.getKeyboard().getKeys();
-        final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).width : 0;
+        final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).mWidth : 0;
 
         // HACK: Have the leftmost number in the popup characters right above the key
         boolean isNumberAtLeftmost =
                 hasMultiplePopupChars(popupKey) && isNumberAtLeftmostPopupChar(popupKey);
-        int popupX = popupKey.x + mWindowOffset[0];
+        int popupX = popupKey.mX + mWindowOffset[0];
         popupX += getPaddingLeft();
         if (isNumberAtLeftmost) {
-            popupX += popupKey.width - miniKeyWidth;  // adjustment for a) described above
+            popupX += popupKey.mWidth - miniKeyWidth;  // adjustment for a) described above
             popupX -= container.getPaddingLeft();
         } else {
             popupX += miniKeyWidth;  // adjustment for b) described above
             popupX -= container.getMeasuredWidth();
             popupX += container.getPaddingRight();
         }
-        int popupY = popupKey.y + mWindowOffset[1];
+        int popupY = popupKey.mY + mWindowOffset[1];
         popupY += getPaddingTop();
         popupY -= container.getMeasuredHeight();
         popupY += container.getPaddingBottom();
@@ -1208,7 +1205,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0];
         mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1];
         mMiniKeyboard.setPopupOffset(adjustedX, y);
-        // TODO: change the below line to use getLatinKeyboard() instead of getKeyboard()
         Keyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard();
         if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null
                 ? false : mKeyboard.isShiftedOrShiftLocked())) {
@@ -1224,8 +1220,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         // Inject down event on the key to mini keyboard.
         long eventTime = SystemClock.uptimeMillis();
         mMiniKeyboardPopupTime = eventTime;
-        MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.x
-                + popupKey.width / 2, popupKey.y + popupKey.height / 2, eventTime);
+        MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.mX
+                + popupKey.mWidth / 2, popupKey.mY + popupKey.mHeight / 2, eventTime);
         mMiniKeyboard.onTouchEvent(downEvent);
         downEvent.recycle();
 
@@ -1234,15 +1230,15 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
     }
 
     private static boolean hasMultiplePopupChars(Key key) {
-        if (key.popupCharacters != null && key.popupCharacters.length() > 1) {
+        if (key.mPopupCharacters != null && key.mPopupCharacters.length() > 1) {
             return true;
         }
         return false;
     }
 
     private static boolean isNumberAtLeftmostPopupChar(Key key) {
-        if (key.popupCharacters != null && key.popupCharacters.length() > 0
-                && isAsciiDigit(key.popupCharacters.charAt(0))) {
+        if (key.mPopupCharacters != null && key.mPopupCharacters.length() > 0
+                && isAsciiDigit(key.mPopupCharacters.charAt(0))) {
             return true;
         }
         return false;
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKey.java b/java/src/com/android/inputmethod/keyboard/LatinKey.java
index 4eaf4c8f6f9c8f8a4d3e10049cafea859331f050..1df4227ae31ae1c3171194f57daf3949c7efb4e6 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKey.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKey.java
@@ -19,47 +19,11 @@ package com.android.inputmethod.keyboard;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 
+// TODO: We should remove this class
 public class LatinKey extends Key {
-
-    // functional normal state (with properties)
-    private final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
-            android.R.attr.state_single
-    };
-
-    // functional pressed state (with properties)
-    private final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
-            android.R.attr.state_single,
-            android.R.attr.state_pressed
-    };
-
-    private boolean mShiftLockEnabled;
-
     public LatinKey(Resources res, Row parent, int x, int y,
             XmlResourceParser parser, KeyStyles keyStyles) {
         super(res, parent, x, y, parser, keyStyles);
-        if (popupCharacters != null && popupCharacters.length() == 0) {
-            // If there is a keyboard with no keys specified in popupCharacters
-            popupResId = 0;
-        }
-    }
-
-    void enableShiftLock() {
-        mShiftLockEnabled = true;
-    }
-
-    // sticky is used for shift key.  If a key is not sticky and is modifier,
-    // the key will be treated as functional.
-    private boolean isFunctionalKey() {
-        return !sticky && modifier;
-    }
-
-    @Override
-    public void onReleased(boolean inside) {
-        if (!mShiftLockEnabled) {
-            super.onReleased(inside);
-        } else {
-            pressed = !pressed;
-        }
     }
 
     /**
@@ -67,24 +31,12 @@ public class LatinKey extends Key {
      */
     @Override
     public boolean isInside(int x, int y) {
-        boolean result = (keyboard instanceof LatinKeyboard)
-                && ((LatinKeyboard)keyboard).isInside(this, x, y);
+        boolean result = (mKeyboard instanceof LatinKeyboard)
+                && ((LatinKeyboard)mKeyboard).isInside(this, x, y);
         return result;
     }
 
     boolean isInsideSuper(int x, int y) {
         return super.isInside(x, y);
     }
-
-    @Override
-    public int[] getCurrentDrawableState() {
-        if (isFunctionalKey()) {
-            if (pressed) {
-                return KEY_STATE_FUNCTIONAL_PRESSED;
-            } else {
-                return KEY_STATE_FUNCTIONAL_NORMAL;
-            }
-        }
-        return super.getCurrentDrawableState();
-    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 29f749a46d2da17ec291af6b43be583465714b30..934874868937ee8439f24b8b9f28eb27cf274313 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SubtypeSwitcher;
 
@@ -34,36 +33,23 @@ import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.Log;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
+// TODO: We should remove this class
 public class LatinKeyboard extends Keyboard {
 
     private static final boolean DEBUG_PREFERRED_LETTER = false;
     private static final String TAG = "LatinKeyboard";
 
-    public static final int KEYCODE_OPTIONS = -100;
-    public static final int KEYCODE_OPTIONS_LONGPRESS = -101;
-    // TODO: remove this once LatinIME stops referring to this.
-    public static final int KEYCODE_VOICE = -102;
-    public static final int KEYCODE_NEXT_LANGUAGE = -104;
-    public static final int KEYCODE_PREV_LANGUAGE = -105;
-    public static final int KEYCODE_CAPSLOCK = -106;
-
-    static final int OPACITY_FULLY_OPAQUE = 255;
+    public static final int OPACITY_FULLY_OPAQUE = 255;
     private static final int SPACE_LED_LENGTH_PERCENT = 80;
 
     private Drawable mShiftLockPreviewIcon;
-    private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
-    private Drawable mSpaceIcon;
     private Drawable mSpaceAutoCompletionIndicator;
-    private Drawable mSpacePreviewIcon;
     private final Drawable mButtonArrowLeftIcon;
     private final Drawable mButtonArrowRightIcon;
     private final int mSpaceBarTextShadowColor;
-    private Key mSpaceKey;
     private int mSpaceKeyIndex = -1;
     private int mSpaceDragStartX;
     private int mSpaceDragLastDiff;
@@ -77,8 +63,6 @@ public class LatinKeyboard extends Keyboard {
     private int mPrefLetterY;
     private int mPrefDistance;
 
-    private LatinKeyboardShiftState mShiftState = new LatinKeyboardShiftState();
-
     private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
     private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
     private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
@@ -111,99 +95,13 @@ public class LatinKeyboard extends Keyboard {
         mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right);
         sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
                 R.dimen.spacebar_vertical_correction);
-        mSpaceKeyIndex = indexOf(LatinIME.KEYCODE_SPACE);
+        mSpaceKeyIndex = indexOf(CODE_SPACE);
     }
 
     @Override
     protected Key createKeyFromXml(Resources res, Row parent, int x, int y, 
             XmlResourceParser parser, KeyStyles keyStyles) {
-        Key key = new LatinKey(res, parent, x, y, parser, keyStyles);
-        switch (key.codes[0]) {
-        case LatinIME.KEYCODE_SPACE:
-            mSpaceKey = key;
-            mSpaceIcon = key.icon;
-            mSpacePreviewIcon = key.iconPreview;
-            break;
-        }
-
-        return key;
-    }
-
-    public void enableShiftLock() {
-        for (final Key key : getShiftKeys()) {
-            if (key instanceof LatinKey) {
-                ((LatinKey)key).enableShiftLock();
-            }
-            mNormalShiftIcons.put(key, key.icon);
-        }
-    }
-
-    public boolean setShiftLocked(boolean newShiftLockState) {
-        final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
-        for (final Key key : getShiftKeys()) {
-            key.on = newShiftLockState;
-            key.icon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key);
-        }
-        mShiftState.setShiftLocked(newShiftLockState);
-        return true;
-    }
-
-    public boolean isShiftLocked() {
-        return mShiftState.isShiftLocked();
-    }
-
-    @Override
-    public boolean setShifted(boolean newShiftState) {
-        if (getShiftKeys().size() == 0)
-            return super.setShifted(newShiftState);
-
-        final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
-        for (final Key key : getShiftKeys()) {
-            if (!newShiftState && !mShiftState.isShiftLocked()) {
-                key.icon = mNormalShiftIcons.get(key);
-            } else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
-                key.icon = shiftedIcons.get(key);
-            }
-        }
-        return mShiftState.setShifted(newShiftState);
-    }
-
-    @Override
-    public boolean isShiftedOrShiftLocked() {
-        if (getShiftKeys().size() > 0) {
-            return mShiftState.isShiftedOrShiftLocked();
-        } else {
-            return super.isShiftedOrShiftLocked();
-        }
-    }
-
-    public void setAutomaticTemporaryUpperCase() {
-        setShifted(true);
-        mShiftState.setAutomaticTemporaryUpperCase();
-    }
-
-    public boolean isAutomaticTemporaryUpperCase() {
-        return isAlphaKeyboard() && mShiftState.isAutomaticTemporaryUpperCase();
-    }
-
-    public boolean isManualTemporaryUpperCase() {
-        return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
-    }
-
-    public LatinKeyboardShiftState getKeyboardShiftState() {
-        return mShiftState;
-    }
-
-    public boolean isAlphaKeyboard() {
-        return mId.getXmlId() == R.xml.kbd_qwerty;
-    }
-
-    public boolean isPhoneKeyboard() {
-        return mId.mMode == KeyboardId.MODE_PHONE;
-    }
-
-    public boolean isNumberKeyboard() {
-        return mId.mMode == KeyboardId.MODE_NUMBER;
+        return new LatinKey(res, parent, x, y, parser, keyStyles);
     }
 
     /**
@@ -218,15 +116,15 @@ public class LatinKeyboard extends Keyboard {
         final Resources res = mRes;
         // If application locales are explicitly selected.
         if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
-            mSpaceKey.icon = new BitmapDrawable(res,
+            mSpaceKey.mIcon = new BitmapDrawable(res,
                     drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
         } else {
             // sym_keyboard_space_led can be shared with Black and White symbol themes.
             if (isAutoCompletion) {
-                mSpaceKey.icon = new BitmapDrawable(res,
+                mSpaceKey.mIcon = new BitmapDrawable(res,
                         drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
             } else {
-                mSpaceKey.icon = mSpaceIcon;
+                mSpaceKey.mIcon = mSpaceIcon;
             }
         }
     }
@@ -283,7 +181,7 @@ public class LatinKeyboard extends Keyboard {
 
     @SuppressWarnings("unused")
     private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion) {
-        final int width = mSpaceKey.width;
+        final int width = mSpaceKey.mWidth;
         final int height = mSpaceIcon.getIntrinsicHeight();
         final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         final Canvas canvas = new Canvas(buffer);
@@ -341,26 +239,26 @@ public class LatinKeyboard extends Keyboard {
 
     private void updateLocaleDrag(int diff) {
         if (mSlidingLocaleIcon == null) {
-            final int width = Math.max(mSpaceKey.width,
+            final int width = Math.max(mSpaceKey.mWidth,
                     (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
             final int height = mSpacePreviewIcon.getIntrinsicHeight();
             mSlidingLocaleIcon =
                     new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height);
             mSlidingLocaleIcon.setBounds(0, 0, width, height);
-            mSpaceKey.iconPreview = mSlidingLocaleIcon;
+            mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
         }
         mSlidingLocaleIcon.setDiff(diff);
         if (Math.abs(diff) == Integer.MAX_VALUE) {
-            mSpaceKey.iconPreview = mSpacePreviewIcon;
+            mSpaceKey.mPreviewIcon = mSpacePreviewIcon;
         } else {
-            mSpaceKey.iconPreview = mSlidingLocaleIcon;
+            mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
         }
-        mSpaceKey.iconPreview.invalidateSelf();
+        mSpaceKey.mPreviewIcon.invalidateSelf();
     }
 
     public int getLanguageChangeDirection() {
         if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1
-                || Math.abs(mSpaceDragLastDiff) < mSpaceKey.width * SPACEBAR_DRAG_THRESHOLD) {
+                || Math.abs(mSpaceDragLastDiff) < mSpaceKey.mWidth * SPACEBAR_DRAG_THRESHOLD) {
             return 0; // No change
         }
         return mSpaceDragLastDiff > 0 ? 1 : -1;
@@ -393,12 +291,12 @@ public class LatinKeyboard extends Keyboard {
      */
     @SuppressWarnings("unused")
     public boolean isInside(LatinKey key, int x, int y) {
-        final int code = key.codes[0];
-        if (code == KEYCODE_SHIFT || code == KEYCODE_DELETE) {
-            y -= key.height / 10;
-            if (code == KEYCODE_SHIFT) x += key.width / 6;
-            if (code == KEYCODE_DELETE) x -= key.width / 6;
-        } else if (code == LatinIME.KEYCODE_SPACE) {
+        final int code = key.mCodes[0];
+        if (code == CODE_SHIFT || code == CODE_DELETE) {
+            y -= key.mHeight / 10;
+            if (code == CODE_SHIFT) x += key.mWidth / 6;
+            if (code == CODE_DELETE) x -= key.mWidth / 6;
+        } else if (code == CODE_SPACE) {
             y += LatinKeyboard.sSpacebarVerticalCorrection;
             if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER
                     && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) {
@@ -447,11 +345,11 @@ public class LatinKeyboard extends Keyboard {
                         mPrefLetterY = y;
                         for (int i = 0; i < nearby.length; i++) {
                             Key k = nearbyKeys.get(nearby[i]);
-                            if (k != key && inPrefList(k.codes[0], pref)) {
+                            if (k != key && inPrefList(k.mCodes[0], pref)) {
                                 final int dist = distanceFrom(k, x, y);
-                                if (dist < (int) (k.width * OVERLAP_PERCENTAGE_LOW_PROB) &&
-                                        (pref[k.codes[0]] > pref[mPrefLetter] * 3))  {
-                                    mPrefLetter = k.codes[0];
+                                if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_LOW_PROB) &&
+                                        (pref[k.mCodes[0]] > pref[mPrefLetter] * 3))  {
+                                    mPrefLetter = k.mCodes[0];
                                     mPrefDistance = dist;
                                     if (DEBUG_PREFERRED_LETTER) {
                                         Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!");
@@ -475,11 +373,11 @@ public class LatinKeyboard extends Keyboard {
 
                 for (int i = 0; i < nearby.length; i++) {
                     Key k = nearbyKeys.get(nearby[i]);
-                    if (inPrefList(k.codes[0], pref)) {
+                    if (inPrefList(k.mCodes[0], pref)) {
                         final int dist = distanceFrom(k, x, y);
-                        if (dist < (int) (k.width * OVERLAP_PERCENTAGE_HIGH_PROB)
+                        if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_HIGH_PROB)
                                 && dist < mPrefDistance)  {
-                            mPrefLetter = k.codes[0];
+                            mPrefLetter = k.mCodes[0];
                             mPrefLetterX = x;
                             mPrefLetterY = y;
                             mPrefDistance = dist;
@@ -507,8 +405,8 @@ public class LatinKeyboard extends Keyboard {
     }
 
     private int distanceFrom(Key k, int x, int y) {
-        if (y > k.y && y < k.y + k.height) {
-            return Math.abs(k.x + k.width / 2 - x);
+        if (y > k.mY && y < k.mY + k.mHeight) {
+            return Math.abs(k.mX + k.mWidth / 2 - x);
         } else {
             return Integer.MAX_VALUE;
         }
@@ -529,7 +427,7 @@ public class LatinKeyboard extends Keyboard {
         List<Key> keys = getKeys();
         int count = keys.size();
         for (int i = 0; i < count; i++) {
-            if (keys.get(i).codes[0] == code) return i;
+            if (keys.get(i).mCodes[0] == code) return i;
         }
         return -1;
     }
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 55427d23f0f9e87e0f3cd849a8a51fca953c9561..4e0caa1f6e72e938d5a33ed29f3f879d13f54eb7 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -31,6 +31,7 @@ import android.view.MotionEvent;
 
 import java.util.List;
 
+// TODO: We should remove this class
 public class LatinKeyboardView extends KeyboardView {
 
     /** Whether we've started dropping move events because we found a big jump */
@@ -86,9 +87,9 @@ public class LatinKeyboardView extends KeyboardView {
 
     @Override
     protected boolean onLongPress(Key key) {
-        int primaryCode = key.codes[0];
-        if (primaryCode == LatinKeyboard.KEYCODE_OPTIONS) {
-            return invokeOnKey(LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS);
+        int primaryCode = key.mCodes[0];
+        if (primaryCode == Keyboard.CODE_OPTIONS) {
+            return invokeOnKey(Keyboard.CODE_OPTIONS_LONGPRESS);
         } else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
             // Long pressing on 0 in phone number keypad gives you a '+'.
             return invokeOnKey('+');
@@ -216,7 +217,7 @@ public class LatinKeyboardView extends KeyboardView {
             if (languageDirection != 0) {
                 getOnKeyboardActionListener().onKey(
                         languageDirection == 1
-                        ? LatinKeyboard.KEYCODE_NEXT_LANGUAGE : LatinKeyboard.KEYCODE_PREV_LANGUAGE,
+                        ? Keyboard.CODE_NEXT_LANGUAGE : Keyboard.CODE_PREV_LANGUAGE,
                         null, mLastX, mLastY);
                 me.setAction(MotionEvent.ACTION_CANCEL);
                 keyboard.keyReleased();
@@ -271,8 +272,8 @@ public class LatinKeyboardView extends KeyboardView {
                                     }
                                     c = mStringToPlay.charAt(mStringIndex);
                                 }
-                                int x = mAsciiKeys[c].x + 10;
-                                int y = mAsciiKeys[c].y + 26;
+                                int x = mAsciiKeys[c].mX + 10;
+                                int y = mAsciiKeys[c].mY + 26;
                                 MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
                                         SystemClock.uptimeMillis(),
                                         MotionEvent.ACTION_DOWN, x, y, 0);
@@ -284,8 +285,8 @@ public class LatinKeyboardView extends KeyboardView {
                                 break;
                             case MSG_TOUCH_UP:
                                 char cUp = mStringToPlay.charAt(mStringIndex);
-                                int x2 = mAsciiKeys[cUp].x + 10;
-                                int y2 = mAsciiKeys[cUp].y + 26;
+                                int x2 = mAsciiKeys[cUp].mX + 10;
+                                int y2 = mAsciiKeys[cUp].mY + 26;
                                 mStringIndex++;
 
                                 MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
@@ -309,7 +310,7 @@ public class LatinKeyboardView extends KeyboardView {
         List<Key> keys = getLatinKeyboard().getKeys();
         // Get the keys on this keyboard
         for (int i = 0; i < keys.size(); i++) {
-            int code = keys.get(i).codes[0];
+            int code = keys.get(i).mCodes[0];
             if (code >= 0 && code <= 255) {
                 mAsciiKeys[code] = keys.get(i);
             }
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index 53879cde11ebc0a14e5e3cbfd1c3862f271dfd90..774b39ab7ff9ad88c30cbea87f67c07e0aba2e3d 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -52,7 +52,7 @@ public class MiniKeyboardKeyDetector extends KeyDetector {
         }
 
         if (allKeys != null && closestKeyIndex != NOT_A_KEY)
-            allKeys[0] = keys[closestKeyIndex].codes[0];
+            allKeys[0] = keys[closestKeyIndex].mCodes[0];
         return closestKeyIndex;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/ModifierKeyState.java
rename to java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
index eb1204f7052f91071267104c49d415640a821efb..1bd3d804074abe5c03a3b9a9267b852627c2b8e0 100644
--- a/java/src/com/android/inputmethod/latin/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
@@ -14,7 +14,7 @@
  * the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.keyboard;
 
 import android.util.Log;
 
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index aa0f9bd3758da44aafdd35fe625cafa2c3e975f9..269ae15301f1a00ee1e2658fd378b9c41bfb6e2d 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -17,7 +17,6 @@
 package com.android.inputmethod.keyboard;
 
 import com.android.inputmethod.keyboard.KeyboardView.UIHandler;
-import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.R;
 
 import android.content.res.Resources;
@@ -45,7 +44,7 @@ public class PointerTracker {
 
     // Miscellaneous constants
     private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY;
-    private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE };
+    private static final int[] KEY_DELETE = { Keyboard.CODE_DELETE };
 
     private final UIProxy mProxy;
     private final UIHandler mHandler;
@@ -207,9 +206,9 @@ public class PointerTracker {
         Key key = getKey(keyIndex);
         if (key == null)
             return false;
-        int primaryCode = key.codes[0];
-        return primaryCode == Keyboard.KEYCODE_SHIFT
-                || primaryCode == Keyboard.KEYCODE_MODE_CHANGE;
+        int primaryCode = key.mCodes[0];
+        return primaryCode == Keyboard.CODE_SHIFT
+                || primaryCode == Keyboard.CODE_MODE_CHANGE;
     }
 
     public boolean isModifier() {
@@ -222,7 +221,7 @@ public class PointerTracker {
 
     public boolean isSpaceKey(int keyIndex) {
         Key key = getKey(keyIndex);
-        return key != null && key.codes[0] == LatinIME.KEYCODE_SPACE;
+        return key != null && key.mCodes[0] == Keyboard.CODE_SPACE;
     }
 
     public void releaseKey() {
@@ -278,14 +277,14 @@ public class PointerTracker {
         checkMultiTap(eventTime, keyIndex);
         if (mListener != null) {
             if (isValidKeyIndex(keyIndex)) {
-                mListener.onPress(mKeys[keyIndex].codes[0]);
+                mListener.onPress(mKeys[keyIndex].mCodes[0]);
                 // This onPress call may have changed keyboard layout and have updated mKeyIndex.
                 // If that's the case, mKeyIndex has been updated in setKeyboard().
                 keyIndex = mKeyState.getKeyIndex();
             }
         }
         if (isValidKeyIndex(keyIndex)) {
-            if (mKeys[keyIndex].repeatable) {
+            if (mKeys[keyIndex].mRepeatable) {
                 repeatKey(keyIndex);
                 mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
                 mIsRepeatableKey = true;
@@ -309,7 +308,7 @@ public class PointerTracker {
                 startLongPressTimer(keyIndex);
             } else if (!isMinorMoveBounce(x, y, keyIndex)) {
                 if (mListener != null)
-                    mListener.onRelease(oldKey.codes[0]);
+                    mListener.onRelease(oldKey.mCodes[0]);
                 resetMultiTap();
                 keyState.onMoveToNewKey(keyIndex, x, y);
                 startLongPressTimer(keyIndex);
@@ -317,7 +316,7 @@ public class PointerTracker {
         } else {
             if (oldKey != null) {
                 if (mListener != null)
-                    mListener.onRelease(oldKey.codes[0]);
+                    mListener.onRelease(oldKey.mCodes[0]);
                 keyState.onMoveToNewKey(keyIndex, x ,y);
                 mHandler.cancelLongPressTimers();
             } else if (!isMinorMoveBounce(x, y, keyIndex)) {
@@ -368,7 +367,7 @@ public class PointerTracker {
         if (key != null) {
             // While key is repeating, because there is no need to handle multi-tap key, we can
             // pass -1 as eventTime argument.
-            detectAndSendKey(keyIndex, key.x, key.y, -1);
+            detectAndSendKey(keyIndex, key.mX, key.mY, -1);
         }
     }
 
@@ -420,18 +419,13 @@ public class PointerTracker {
 
     private void startLongPressTimer(int keyIndex) {
         Key key = getKey(keyIndex);
-        if (key.codes[0] == Keyboard.KEYCODE_SHIFT) {
+        if (key.mCodes[0] == Keyboard.CODE_SHIFT) {
             mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
         } else {
             mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
         }
     }
 
-    private boolean isManualTemporaryUpperCase() {
-        return mKeyboard instanceof LatinKeyboard
-                && ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase();
-    }
-
     private void detectAndSendKey(int index, int x, int y, long eventTime) {
         final KeyboardActionListener listener = mListener;
         final Key key = getKey(index);
@@ -440,30 +434,31 @@ public class PointerTracker {
             if (listener != null)
                 listener.onCancel();
         } else {
-            if (key.text != null) {
+            if (key.mOutputText != null) {
                 if (listener != null) {
-                    listener.onText(key.text);
+                    listener.onText(key.mOutputText);
                     listener.onRelease(NOT_A_KEY);
                 }
             } else {
-                int code = key.codes[0];
+                int code = key.mCodes[0];
                 //TextEntryState.keyPressedAt(key, x, y);
                 int[] codes = mKeyDetector.newCodeArray();
                 mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
                 // Multi-tap
                 if (mInMultiTap) {
                     if (mTapCount != -1) {
-                        mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y);
+                        mListener.onKey(Keyboard.CODE_DELETE, KEY_DELETE, x, y);
                     } else {
                         mTapCount = 0;
                     }
-                    code = key.codes[mTapCount];
+                    code = key.mCodes[mTapCount];
                 }
 
                 // If keyboard is in manual temporary upper case state and key has manual temporary
                 // shift code, alternate character code should be sent.
-                if (isManualTemporaryUpperCase() && key.manualTemporaryUpperCaseCode != 0) {
-                    code = key.manualTemporaryUpperCaseCode;
+                if (mKeyboard.isManualTemporaryUpperCase()
+                        && key.mManualTemporaryUpperCaseCode != 0) {
+                    code = key.mManualTemporaryUpperCaseCode;
                     codes[0] = code;
                 }
 
@@ -493,10 +488,10 @@ public class PointerTracker {
         if (mInMultiTap) {
             // Multi-tap
             mPreviewLabel.setLength(0);
-            mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]);
+            mPreviewLabel.append((char) key.mCodes[mTapCount < 0 ? 0 : mTapCount]);
             return mPreviewLabel;
         } else {
-            return key.label;
+            return key.mLabel;
         }
     }
 
@@ -514,10 +509,10 @@ public class PointerTracker {
 
         final boolean isMultiTap =
                 (eventTime < mLastTapTime + mMultiTapKeyTimeout && keyIndex == mLastSentIndex);
-        if (key.codes.length > 1) {
+        if (key.mCodes.length > 1) {
             mInMultiTap = true;
             if (isMultiTap) {
-                mTapCount = (mTapCount + 1) % key.codes.length;
+                mTapCount = (mTapCount + 1) % key.mCodes.length;
                 return;
             } else {
                 mTapCount = -1;
@@ -536,7 +531,7 @@ public class PointerTracker {
         if (key == null) {
             code = "----";
         } else {
-            int primaryCode = key.codes[0];
+            int primaryCode = key.mCodes[0];
             code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
         }
         Log.d(TAG, String.format("%s%s[%d] %3d,%3d %3d(%s) %s", title,
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
index 047173445bc8d56cf36c48a0c58fd75a1ab5a1bb..43596ae2ed1f80888a8f16ccd7519e79850956c8 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
@@ -53,7 +53,7 @@ public class ProximityKeyDetector extends KeyDetector {
                 }
 
                 if (allKeys == null) continue;
-                final int nCodes = key.codes.length;
+                final int nCodes = key.mCodes.length;
                 // Find insertion point
                 for (int j = 0; j < distances.length; j++) {
                     if (distances[j] > dist) {
@@ -62,7 +62,7 @@ public class ProximityKeyDetector extends KeyDetector {
                                 distances.length - (j + nCodes));
                         System.arraycopy(allKeys, j, allKeys, j + nCodes,
                                 allKeys.length - (j + nCodes));
-                        System.arraycopy(key.codes, 0, allKeys, j, nCodes);
+                        System.arraycopy(key.mCodes, 0, allKeys, j, nCodes);
                         Arrays.fill(distances, j, j + nCodes, dist);
                         break;
                     }
diff --git a/java/src/com/android/inputmethod/keyboard/Row.java b/java/src/com/android/inputmethod/keyboard/Row.java
index cb778f317d39242aa0cf46cb5a01039ecc143a1a..0768b1ff86d7183d0ad56011b6f9a64c5495e876 100644
--- a/java/src/com/android/inputmethod/keyboard/Row.java
+++ b/java/src/com/android/inputmethod/keyboard/Row.java
@@ -30,44 +30,44 @@ import android.util.Xml;
  */
 public class Row {
     /** Default width of a key in this row. */
-    public int defaultWidth;
+    public int mDefaultWidth;
     /** Default height of a key in this row. */
-    public int defaultHeight;
+    public int mDefaultHeight;
     /** Default horizontal gap between keys in this row. */
-    public int defaultHorizontalGap;
+    public int mDefaultHorizontalGap;
     /** Vertical gap following this row. */
-    public int verticalGap;
+    public int mVerticalGap;
     /**
      * Edge flags for this row of keys. Possible values that can be assigned are
      * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM}
      */
-    public int rowEdgeFlags;
+    public int mRowEdgeFlags;
 
-    final Keyboard parent;
+    /* package */ final Keyboard mParent;
 
-    Row(Keyboard parent) {
-        this.parent = parent;
+    /* package */ Row(Keyboard parent) {
+        this.mParent = parent;
     }
 
     public Row(Resources res, Keyboard parent, XmlResourceParser parser) {
-        this.parent = parent;
+        this.mParent = parent;
         TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard);
-        defaultWidth = KeyboardParser.getDimensionOrFraction(a,
+        mDefaultWidth = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_keyWidth,
                 parent.mDisplayWidth, parent.mDefaultWidth);
-        defaultHeight = KeyboardParser.getDimensionOrFraction(a,
+        mDefaultHeight = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_keyHeight,
                 parent.mDisplayHeight, parent.mDefaultHeight);
-        defaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a,
+        mDefaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_horizontalGap,
                 parent.mDisplayWidth, parent.mDefaultHorizontalGap);
-        verticalGap = KeyboardParser.getDimensionOrFraction(a,
+        mVerticalGap = KeyboardParser.getDimensionOrFraction(a,
                 R.styleable.Keyboard_verticalGap,
                 parent.mDisplayHeight, parent.mDefaultVerticalGap);
         a.recycle();
         a = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Row);
-        rowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0);
+        mRowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0);
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
similarity index 97%
rename from java/src/com/android/inputmethod/latin/ShiftKeyState.java
rename to java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
index 7412a566de7c35de7d229a63bcaf856c3396a50d..9229208a950f43c8b32d7cb4eb331d348dfcf7de 100644
--- a/java/src/com/android/inputmethod/latin/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
@@ -14,7 +14,7 @@
  * the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.keyboard;
 
 import android.util.Log;
 
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4f4112fa8fdde5dc6a79b8445db1fa5ab020262b..5bf635fd37791756eafd6efe543abea7fb95e0ab 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -19,8 +19,8 @@ package com.android.inputmethod.latin;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardActionListener;
 import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.LatinKeyboard;
 import com.android.inputmethod.keyboard.LatinKeyboardView;
 import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer;
 import com.android.inputmethod.voice.VoiceIMEConnector;
@@ -109,11 +109,6 @@ public class LatinIME extends InputMethodService
     // Key events coming any faster than this are long-presses.
     private static final int QUICK_PRESS = 200;
 
-    public static final int KEYCODE_ENTER = '\n';
-    public static final int KEYCODE_TAB = '\t';
-    public static final int KEYCODE_SPACE = ' ';
-    public static final int KEYCODE_PERIOD = '.';
-
     // Contextual menu positions
     private static final int POS_METHOD = 0;
     private static final int POS_SETTINGS = 1;
@@ -255,7 +250,7 @@ public class LatinIME extends InputMethodService
         }
     }
 
-    /* package */ final UIHandler mHandler = new UIHandler();
+    public final UIHandler mHandler = new UIHandler();
 
     public class UIHandler extends Handler {
         private static final int MSG_UPDATE_SUGGESTIONS = 0;
@@ -968,7 +963,8 @@ public class LatinIME extends InputMethodService
         if (ic == null) return;
         CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
         if (lastTwo != null && lastTwo.length() == 2
-                && lastTwo.charAt(0) == KEYCODE_SPACE && isSentenceSeparator(lastTwo.charAt(1))) {
+                && lastTwo.charAt(0) == Keyboard.CODE_SPACE
+                && isSentenceSeparator(lastTwo.charAt(1))) {
             ic.beginBatchEdit();
             ic.deleteSurroundingText(2, 0);
             ic.commitText(lastTwo.charAt(1) + " ", 1);
@@ -983,9 +979,9 @@ public class LatinIME extends InputMethodService
         if (ic == null) return;
         CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
         if (lastThree != null && lastThree.length() == 3
-                && lastThree.charAt(0) == KEYCODE_PERIOD
-                && lastThree.charAt(1) == KEYCODE_SPACE
-                && lastThree.charAt(2) == KEYCODE_PERIOD) {
+                && lastThree.charAt(0) == Keyboard.CODE_PERIOD
+                && lastThree.charAt(1) == Keyboard.CODE_SPACE
+                && lastThree.charAt(2) == Keyboard.CODE_PERIOD) {
             ic.beginBatchEdit();
             ic.deleteSurroundingText(3, 0);
             ic.commitText(" ..", 1);
@@ -1002,7 +998,8 @@ public class LatinIME extends InputMethodService
         CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
         if (lastThree != null && lastThree.length() == 3
                 && Character.isLetterOrDigit(lastThree.charAt(0))
-                && lastThree.charAt(1) == KEYCODE_SPACE && lastThree.charAt(2) == KEYCODE_SPACE) {
+                && lastThree.charAt(1) == Keyboard.CODE_SPACE
+                && lastThree.charAt(2) == Keyboard.CODE_SPACE) {
             ic.beginBatchEdit();
             ic.deleteSurroundingText(2, 0);
             ic.commitText(". ", 1);
@@ -1020,8 +1017,8 @@ public class LatinIME extends InputMethodService
         // if there is one.
         CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
         if (lastOne != null && lastOne.length() == 1
-                && lastOne.charAt(0) == KEYCODE_PERIOD
-                && text.charAt(0) == KEYCODE_PERIOD) {
+                && lastOne.charAt(0) == Keyboard.CODE_PERIOD
+                && text.charAt(0) == Keyboard.CODE_PERIOD) {
             ic.deleteSurroundingText(1, 0);
         }
     }
@@ -1032,7 +1029,7 @@ public class LatinIME extends InputMethodService
 
         CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
         if (lastOne != null && lastOne.length() == 1
-                && lastOne.charAt(0) == KEYCODE_SPACE) {
+                && lastOne.charAt(0) == Keyboard.CODE_SPACE) {
             ic.deleteSurroundingText(1, 0);
         }
     }
@@ -1082,57 +1079,57 @@ public class LatinIME extends InputMethodService
     @Override
     public void onKey(int primaryCode, int[] keyCodes, int x, int y) {
         long when = SystemClock.uptimeMillis();
-        if (primaryCode != Keyboard.KEYCODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
+        if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
             mDeleteCount = 0;
         }
         mLastKeyTime = when;
         KeyboardSwitcher switcher = mKeyboardSwitcher;
         final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
         switch (primaryCode) {
-        case Keyboard.KEYCODE_DELETE:
+        case Keyboard.CODE_DELETE:
             handleBackspace();
             mDeleteCount++;
             LatinImeLogger.logOnDelete();
             break;
-        case Keyboard.KEYCODE_SHIFT:
+        case Keyboard.CODE_SHIFT:
             // Shift key is handled in onPress() when device has distinct multi-touch panel.
             if (!distinctMultiTouch)
                 switcher.toggleShift();
             break;
-        case Keyboard.KEYCODE_MODE_CHANGE:
+        case Keyboard.CODE_MODE_CHANGE:
             // Symbol key is handled in onPress() when device has distinct multi-touch panel.
             if (!distinctMultiTouch)
                 switcher.changeKeyboardMode();
             break;
-        case Keyboard.KEYCODE_CANCEL:
+        case Keyboard.CODE_CANCEL:
             if (!isShowingOptionDialog()) {
                 handleClose();
             }
             break;
-        case LatinKeyboard.KEYCODE_OPTIONS:
+        case Keyboard.CODE_OPTIONS:
             onOptionKeyPressed();
             break;
-        case LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS:
+        case Keyboard.CODE_OPTIONS_LONGPRESS:
             onOptionKeyLongPressed();
             break;
-        case LatinKeyboard.KEYCODE_NEXT_LANGUAGE:
+        case Keyboard.CODE_NEXT_LANGUAGE:
             toggleLanguage(false, true);
             break;
-        case LatinKeyboard.KEYCODE_PREV_LANGUAGE:
+        case Keyboard.CODE_PREV_LANGUAGE:
             toggleLanguage(false, false);
             break;
-        case LatinKeyboard.KEYCODE_CAPSLOCK:
+        case Keyboard.CODE_CAPSLOCK:
             switcher.toggleCapsLock();
             break;
-        case LatinKeyboard.KEYCODE_VOICE: /* was a button press, was not a swipe */
+        case Keyboard.CODE_VOICE: /* was a button press, was not a swipe */
             mVoiceConnector.startListening(false,
                     mKeyboardSwitcher.getInputView().getWindowToken(), mConfigurationChanging);
             break;
-        case KEYCODE_TAB:
+        case Keyboard.CODE_TAB:
             handleTab();
             break;
         default:
-            if (primaryCode != KEYCODE_ENTER) {
+            if (primaryCode != Keyboard.CODE_ENTER) {
                 mJustAddedAutoSpace = false;
             }
             RingCharBuffer.getInstance().push((char)primaryCode, x, y);
@@ -1344,14 +1341,14 @@ public class LatinIME extends InputMethodService
                 pickedDefault = pickDefaultSuggestion();
                 // Picked the suggestion by the space key.  We consider this
                 // as "added an auto space".
-                if (primaryCode == KEYCODE_SPACE) {
+                if (primaryCode == Keyboard.CODE_SPACE) {
                     mJustAddedAutoSpace = true;
                 }
             } else {
                 commitTyped(ic);
             }
         }
-        if (mJustAddedAutoSpace && primaryCode == KEYCODE_ENTER) {
+        if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) {
             removeTrailingSpace();
             mJustAddedAutoSpace = false;
         }
@@ -1360,15 +1357,15 @@ public class LatinIME extends InputMethodService
         // Handle the case of ". ." -> " .." with auto-space if necessary
         // before changing the TextEntryState.
         if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
-                && primaryCode == KEYCODE_PERIOD) {
+                && primaryCode == Keyboard.CODE_PERIOD) {
             reswapPeriodAndSpace();
         }
 
         TextEntryState.typedCharacter((char) primaryCode, true);
         if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
-                && primaryCode != KEYCODE_ENTER) {
+                && primaryCode != Keyboard.CODE_ENTER) {
             swapPunctuationAndSpace();
-        } else if (isPredictionOn() && primaryCode == KEYCODE_SPACE) {
+        } else if (isPredictionOn() && primaryCode == Keyboard.CODE_SPACE) {
             doubleSpace();
         }
         if (pickedDefault) {
@@ -1629,7 +1626,7 @@ public class LatinIME extends InputMethodService
             // Fool the state watcher so that a subsequent backspace will not do a revert, unless
             // we just did a correction, in which case we need to stay in
             // TextEntryState.State.PICKED_SUGGESTION state.
-            TextEntryState.typedCharacter((char) KEYCODE_SPACE, true);
+            TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true);
             setPunctuationSuggestions();
         } else if (!showingAddToDictionaryHint) {
             // If we're not showing the "Touch again to save", then show corrections again.
@@ -1857,7 +1854,7 @@ public class LatinIME extends InputMethodService
     }
 
     private void sendSpace() {
-        sendKeyChar((char)KEYCODE_SPACE);
+        sendKeyChar((char)Keyboard.CODE_SPACE);
         mKeyboardSwitcher.updateShiftState();
         //onKey(KEY_SPACE[0], KEY_SPACE);
     }
@@ -1930,9 +1927,9 @@ public class LatinIME extends InputMethodService
         playKeyClick(primaryCode);
         KeyboardSwitcher switcher = mKeyboardSwitcher;
         final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
-        if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
+        if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
             switcher.onPressShift();
-        } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+        } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_MODE_CHANGE) {
             switcher.onPressSymbol();
         } else {
             switcher.onOtherKeyPressed();
@@ -1945,9 +1942,9 @@ public class LatinIME extends InputMethodService
         // Reset any drag flags in the keyboard
         switcher.keyReleased();
         final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
-        if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
+        if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
             switcher.onReleaseShift();
-        } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+        } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_MODE_CHANGE) {
             switcher.onReleaseSymbol();
         }
     }
@@ -1984,13 +1981,13 @@ public class LatinIME extends InputMethodService
             // FIXME: These should be triggered after auto-repeat logic
             int sound = AudioManager.FX_KEYPRESS_STANDARD;
             switch (primaryCode) {
-                case Keyboard.KEYCODE_DELETE:
+                case Keyboard.CODE_DELETE:
                     sound = AudioManager.FX_KEYPRESS_DELETE;
                     break;
-                case KEYCODE_ENTER:
+                case Keyboard.CODE_ENTER:
                     sound = AudioManager.FX_KEYPRESS_RETURN;
                     break;
-                case KEYCODE_SPACE:
+                case Keyboard.CODE_SPACE:
                     sound = AudioManager.FX_KEYPRESS_SPACEBAR;
                     break;
             }
diff --git a/java/src/com/android/inputmethod/latin/LatinIMESettings.java b/java/src/com/android/inputmethod/latin/LatinIMESettings.java
index 187b6d39409518b1eb8885cab25f91d996244120..3aa89dd599d58155abff78835953cf18bde51f4d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIMESettings.java
+++ b/java/src/com/android/inputmethod/latin/LatinIMESettings.java
@@ -48,7 +48,7 @@ public class LatinIMESettings extends PreferenceActivity
     private static final String VOICE_SETTINGS_KEY = "voice_mode";
     private static final String PREF_AUTO_COMPLETION_THRESHOLD = "auto_completion_threshold";
     private static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
-    /* package */ static final String PREF_SETTINGS_KEY = "settings_key";
+    public static final String PREF_SETTINGS_KEY = "settings_key";
     /* package */ static final String PREF_VIBRATE_ON = "vibrate_on";
 
     private static final String TAG = "LatinIMESettings";
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index a9891768993ff54ab7272a83093272d041516fbe..3ee4eb891bfea3df09c267cc93d5bebd7b3f0ac5 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -16,7 +16,7 @@
 
 package com.android.inputmethod.latin;
 
-import com.android.inputmethod.keyboard.LatinKeyboard;
+import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.voice.SettingsUtil;
 import com.android.inputmethod.voice.VoiceIMEConnector;
 import com.android.inputmethod.voice.VoiceInput;
@@ -198,7 +198,7 @@ public class SubtypeSwitcher {
                     || VoiceIMEConnector.getInstance().needsToShowWarningDialog()) {
                 if (mVoiceInput != null) {
                     // TODO: Call proper function to trigger VoiceIME
-                    mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0);
+                    mService.onKey(Keyboard.CODE_VOICE, null, 0, 0);
                 }
             }
         } else {
@@ -351,7 +351,7 @@ public class SubtypeSwitcher {
                 if (DBG) {
                     Log.d(TAG, "Set and call voice input.");
                 }
-                mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0);
+                mService.onKey(Keyboard.CODE_VOICE, null, 0, 0);
                 return true;
             }
         }
diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java
index 31a192bfe3e315bb07237f0a99720e64d4341939..34babdcb5854ec36a2782f14f75be3cbff03e963 100644
--- a/java/src/com/android/inputmethod/latin/TextEntryState.java
+++ b/java/src/com/android/inputmethod/latin/TextEntryState.java
@@ -261,13 +261,13 @@ public class TextEntryState {
     }
 
     public static void keyPressedAt(Key key, int x, int y) {
-        if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) {
-            String out = 
-                    "KEY: " + (char) key.codes[0] 
-                    + " X: " + x 
+        if (LOGGING && sKeyLocationFile != null && key.mCodes[0] >= 32) {
+            String out =
+                    "KEY: " + (char) key.mCodes[0]
+                    + " X: " + x
                     + " Y: " + y
-                    + " MX: " + (key.x + key.width / 2)
-                    + " MY: " + (key.y + key.height / 2) 
+                    + " MX: " + (key.mX + key.mWidth / 2)
+                    + " MY: " + (key.mY + key.mHeight / 2)
                     + "\n";
             try {
                 sKeyLocationFile.write(out.getBytes());
diff --git a/java/src/com/android/inputmethod/latin/Tutorial.java b/java/src/com/android/inputmethod/latin/Tutorial.java
index bd069bd0d8c545ccb596ddd8bd9066caee3937e8..20767de4dbbf3dc749216aef896502d1671f9f64 100644
--- a/java/src/com/android/inputmethod/latin/Tutorial.java
+++ b/java/src/com/android/inputmethod/latin/Tutorial.java
@@ -16,6 +16,7 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.LatinKeyboardView;
 
 import android.content.Context;
diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
index 73b3b19e3e4f2d6f43a6ae0d5213522ea8f4e2cc..7ad6c35a05ff472199f5cd1963cd6b96f8f27b29 100644
--- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
+++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
@@ -16,8 +16,8 @@
 
 package com.android.inputmethod.voice;
 
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.latin.EditingUtil;
-import com.android.inputmethod.latin.KeyboardSwitcher;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinIME.UIHandler;
 import com.android.inputmethod.latin.R;