diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d4aab40..b68d482 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -186,7 +186,6 @@
     private InputMethodManagerCompatWrapper mImm;
     private Resources mResources;
     private SharedPreferences mPrefs;
-    private String mInputMethodId;
     private KeyboardSwitcher mKeyboardSwitcher;
     private SubtypeSwitcher mSubtypeSwitcher;
     private VoiceProxy mVoiceProxy;
@@ -496,7 +495,6 @@
         super.onCreate();
 
         mImm = InputMethodManagerCompatWrapper.getInstance();
-        mInputMethodId = Utils.getInputMethodId(mImm, getPackageName());
         mSubtypeSwitcher = SubtypeSwitcher.getInstance();
         mKeyboardSwitcher = KeyboardSwitcher.getInstance();
         mVibrator = VibratorCompatWrapper.getInstance(this);
@@ -738,8 +736,6 @@
 
         mSubtypeSwitcher.updateParametersOnStartInputView();
 
-        TextEntryState.reset();
-
         // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
         // know now whether this is a password text field, because we need to know now whether we
         // want to enable the voice button.
@@ -932,7 +928,6 @@
                     && (selectionChanged || candidatesCleared)) {
                 mWordComposer.reset();
                 mHasUncommittedTypedChars = false;
-                TextEntryState.reset();
                 updateSuggestions();
                 final InputConnection ic = getCurrentInputConnection();
                 if (ic != null) {
@@ -941,7 +936,6 @@
                 mComposingStateManager.onFinishComposingText();
                 mVoiceProxy.setVoiceInputHighlighted(false);
             } else if (!mHasUncommittedTypedChars) {
-                TextEntryState.reset();
                 updateSuggestions();
             }
         }
@@ -1149,7 +1143,6 @@
             if (ic != null) {
                 ic.commitText(typedWord, 1);
             }
-            TextEntryState.acceptedTyped(typedWord);
             addToUserUnigramAndBigramDictionaries(typedWord,
                     UserUnigramDictionary.FREQUENCY_FOR_TYPED);
         }
@@ -1427,8 +1420,6 @@
         }
         mHandler.postUpdateShiftKeyState();
 
-        // TODO: Merge space state with TextEntryState
-        TextEntryState.backspace();
         if (null != mWordSavedForAutoCorrectCancellation) {
             Utils.Stats.onAutoCorrectionCancellation();
             cancelAutoCorrect(ic);
@@ -1575,10 +1566,8 @@
 
         switcher.updateShiftState();
         if (mSettingsValues.isWordSeparator(code)) {
-            TextEntryState.typedCharacter((char) code, true, x, y);
             Utils.Stats.onSeparator((char)code, x, y);
         } else {
-            TextEntryState.typedCharacter((char) code, false, x, y);
             Utils.Stats.onNonSeparator((char)code, x, y);
         }
         if (null != ic) ic.endBatchEdit();
@@ -1662,12 +1651,10 @@
             setPunctuationSuggestions();
         }
 
-        TextEntryState.typedCharacter((char) primaryCode, true, x, y);
         Utils.Stats.onSeparator((char)primaryCode, x, y);
 
         if (pickedDefault) {
             CharSequence typedWord = mWordComposer.getTypedWord();
-            TextEntryState.backToAcceptedDefault(typedWord);
             if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) {
                 InputConnectionCompatUtils.commitCorrection(
                         ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
@@ -1877,8 +1864,6 @@
         if (mBestWord != null && mBestWord.length() > 0) {
             Utils.Stats.onAutoCorrection(mWordComposer.getTypedWord(), mBestWord.toString(),
                     separatorCode);
-            TextEntryState.acceptedDefault(mWordComposer.getTypedWord(), mBestWord,
-                    separatorCode);
             mExpectingUpdateSelection = true;
             commitBestWord(mBestWord);
             if (!mBestWord.equals(mWordComposer.getTypedWord())) {
@@ -1959,7 +1944,6 @@
         }
         LatinImeLogger.logOnManualSuggestion(mWordComposer.getTypedWord().toString(),
                 suggestion.toString(), index, suggestions.mWords);
-        TextEntryState.acceptedSuggestion(mWordComposer.getTypedWord().toString(), suggestion);
         // Follow it with a space
         if (mInsertSpaceOnPickSuggestionManually) {
             sendMagicSpace();
@@ -1981,11 +1965,6 @@
                         || !AutoCorrection.isValidWord(
                                 mSuggest.getUnigramDictionaries(), suggestion, true));
 
-        // 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) Keyboard.CODE_SPACE, true,
-                WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
         Utils.Stats.onSeparator((char)Keyboard.CODE_SPACE, WordComposer.NOT_A_COORDINATE,
                 WordComposer.NOT_A_COORDINATE);
         if (!showingAddToDictionaryHint) {
@@ -2174,7 +2153,6 @@
         mBestWord = null;
         mHasUncommittedTypedChars = true;
         mComposingStateManager.onStartComposingText();
-        TextEntryState.restartSuggestionsOnWordBeforeCursor();
         ic.deleteSurroundingText(word.length(), 0);
         ic.setComposingText(word, 1);
         mHandler.postUpdateSuggestions();
@@ -2203,10 +2181,7 @@
 
         // Re-insert the separator
         ic.commitText(mWordComposer.getTypedWord(), 1);
-        TextEntryState.acceptedTyped(mWordComposer.getTypedWord());
         ic.commitText(separator, 1);
-        TextEntryState.typedCharacter(separator.charAt(0), true,
-                WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
         Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
                 WordComposer.NOT_A_COORDINATE);
         mHandler.cancelUpdateBigramPredictions();
@@ -2237,7 +2212,6 @@
         // the old WordComposer allows to reuse the actual typed coordinates.
         mHasUncommittedTypedChars = true;
         ic.setComposingText(mWordComposer.getTypedWord(), 1);
-        TextEntryState.backspace();
         mHandler.cancelUpdateBigramPredictions();
         mHandler.postUpdateSuggestions();
     }
@@ -2462,7 +2436,8 @@
                 switch (position) {
                 case 0:
                     Intent intent = CompatUtils.getInputLanguageSelectionIntent(
-                            mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK
+                            Utils.getInputMethodId(mImm, getPackageName()),
+                            Intent.FLAG_ACTIVITY_NEW_TASK
                             | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                             | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                     startActivity(intent);
@@ -2520,7 +2495,6 @@
         p.println("  mAutoCorrectEnabled=" + mSettingsValues.mAutoCorrectEnabled);
         p.println("  mInsertSpaceOnPickSuggestionManually=" + mInsertSpaceOnPickSuggestionManually);
         p.println("  mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
-        p.println("  TextEntryState.state=" + TextEntryState.getState());
         p.println("  mSoundOn=" + mSettingsValues.mSoundOn);
         p.println("  mVibrateOn=" + mSettingsValues.mVibrateOn);
         p.println("  mKeyPreviewPopupOn=" + mSettingsValues.mKeyPreviewPopupOn);
diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java
deleted file mode 100644
index ebaecf7..0000000
--- a/java/src/com/android/inputmethod/latin/TextEntryState.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.latin;
-
-import com.android.inputmethod.keyboard.Keyboard;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-public class TextEntryState {
-    private static final String TAG = TextEntryState.class.getSimpleName();
-    private static final boolean DEBUG = false;
-
-    private static final int UNKNOWN = 0;
-    private static final int START = 1;
-    private static final int IN_WORD = 2;
-    private static final int ACCEPTED_DEFAULT = 3;
-    private static final int PICKED_SUGGESTION = 4;
-    private static final int PUNCTUATION_AFTER_ACCEPTED = 5;
-    private static final int SPACE_AFTER_ACCEPTED = 6;
-    private static final int SPACE_AFTER_PICKED = 7;
-    private static final int UNDO_COMMIT = 8;
-
-    private static int sState = UNKNOWN;
-    private static int sPreviousState = UNKNOWN;
-
-    private static void setState(final int newState) {
-        sPreviousState = sState;
-        sState = newState;
-    }
-
-    public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord,
-            int separatorCode) {
-        if (TextUtils.isEmpty(typedWord)) return;
-        setState(ACCEPTED_DEFAULT);
-        if (DEBUG)
-            displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord);
-    }
-
-    // State.ACCEPTED_DEFAULT will be changed to other sub-states
-    // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
-    // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
-    public static void backToAcceptedDefault(CharSequence typedWord) {
-        if (TextUtils.isEmpty(typedWord)) return;
-        switch (sState) {
-        case SPACE_AFTER_ACCEPTED:
-        case PUNCTUATION_AFTER_ACCEPTED:
-        case IN_WORD:
-            setState(ACCEPTED_DEFAULT);
-            break;
-        default:
-            break;
-        }
-        if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord);
-    }
-
-    public static void acceptedTyped(CharSequence typedWord) {
-        setState(PICKED_SUGGESTION);
-        if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord);
-    }
-
-    public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
-        setState(PICKED_SUGGESTION);
-        if (DEBUG)
-            displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord);
-    }
-
-    public static void typedCharacter(char c, boolean isSeparator, int x, int y) {
-        final boolean isSpace = (c == Keyboard.CODE_SPACE);
-        switch (sState) {
-        case IN_WORD:
-            if (isSpace || isSeparator) {
-                setState(START);
-            } else {
-                // State hasn't changed.
-            }
-            break;
-        case ACCEPTED_DEFAULT:
-        case SPACE_AFTER_PICKED:
-        case PUNCTUATION_AFTER_ACCEPTED:
-            if (isSpace) {
-                setState(SPACE_AFTER_ACCEPTED);
-            } else if (isSeparator) {
-                // Swap
-                setState(PUNCTUATION_AFTER_ACCEPTED);
-            } else {
-                setState(IN_WORD);
-            }
-            break;
-        case PICKED_SUGGESTION:
-            if (isSpace) {
-                setState(SPACE_AFTER_PICKED);
-            } else if (isSeparator) {
-                // Swap
-                setState(PUNCTUATION_AFTER_ACCEPTED);
-            } else {
-                setState(IN_WORD);
-            }
-            break;
-        case START:
-        case UNKNOWN:
-        case SPACE_AFTER_ACCEPTED:
-            if (!isSpace && !isSeparator) {
-                setState(IN_WORD);
-            } else {
-                setState(START);
-            }
-            break;
-        case UNDO_COMMIT:
-            if (isSpace || isSeparator) {
-                setState(START);
-            } else {
-                setState(IN_WORD);
-            }
-            break;
-        }
-        if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator);
-    }
-    
-    public static void backspace() {
-        if (sState == ACCEPTED_DEFAULT) {
-            setState(UNDO_COMMIT);
-        } else if (sState == UNDO_COMMIT) {
-            setState(IN_WORD);
-        }
-        // TODO: tidy up this logic. At the moment, for example, writing a word goes to
-        // ACCEPTED_DEFAULT, backspace will go to UNDO_COMMIT, another backspace will go to IN_WORD,
-        // and subsequent backspaces will leave the status at IN_WORD, even if the user backspaces
-        // past the end of the word. We are not in a word any more but the state is still IN_WORD.
-        if (DEBUG) displayState("backspace");
-    }
-
-    public static void restartSuggestionsOnWordBeforeCursor() {
-        if (UNKNOWN == sState || ACCEPTED_DEFAULT == sState) {
-            // Here we can come from pretty much any state, except the ones that we can't
-            // come from after backspace, so supposedly anything except UNKNOWN and
-            // ACCEPTED_DEFAULT. Note : we could be in UNDO_COMMIT if
-            // LatinIME#revertLastWord() was calling LatinIME#restartSuggestions...()
-            Log.e(TAG, "Strange state change : coming from state " + sState);
-        }
-        setState(IN_WORD);
-    }
-
-    public static void reset() {
-        setState(START);
-        if (DEBUG) displayState("reset");
-    }
-
-    public static boolean isUndoCommit() {
-        return sState == UNDO_COMMIT;
-    }
-
-    public static String getState() {
-        return stateName(sState);
-    }
-
-    private static String stateName(int state) {
-        switch (state) {
-        case START: return "START";
-        case IN_WORD: return "IN_WORD";
-        case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT";
-        case PICKED_SUGGESTION: return "PICKED_SUGGESTION";
-        case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED";
-        case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED";
-        case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED";
-        case UNDO_COMMIT: return "UNDO_COMMIT";
-        default: return "UNKNOWN";
-        }
-    }
-
-    private static void displayState(String title, Object ... args) {
-        final StringBuilder sb = new StringBuilder(title);
-        sb.append(':');
-        for (int i = 0; i < args.length; i += 2) {
-            sb.append(' ');
-            sb.append(args[i]);
-            sb.append('=');
-            sb.append(args[i+1].toString());
-        }
-        sb.append(" state=");
-        sb.append(stateName(sState));
-        sb.append(" previous=");
-        sb.append(stateName(sPreviousState));
-        Log.d(TAG, sb.toString());
-    }
-}
