Merge "Demote words with a capitalized char"
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index bcce581..a3e8d4a 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -24,7 +24,6 @@
     <bool name="config_default_show_settings_key">false</bool>
     <bool name="config_enable_show_voice_key_option">true</bool>
     <bool name="config_enable_show_popup_on_keypress_option">true</bool>
-    <bool name="config_enable_show_recorrection_option">false</bool>
     <bool name="config_enable_bigram_suggestions_option">true</bool>
     <bool name="config_enable_usability_study_mode_option">false</bool>
     <bool name="config_sliding_key_input_enabled">true</bool>
@@ -37,7 +36,6 @@
     <!-- Default value for bigram prediction: after entering a word and a space only, should we look
          at input history to suggest a hopefully helpful suggestions for the next word? -->
     <bool name="config_default_bigram_prediction">false</bool>
-    <bool name="config_default_compat_recorrection_enabled">true</bool>
     <bool name="config_default_sound_enabled">false</bool>
     <bool name="config_default_vibration_enabled">true</bool>
     <bool name="config_auto_correction_spacebar_led_enabled">true</bool>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 9b3829f..a1f3488 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -326,10 +326,6 @@
     <string name="prefs_enable_log">Enable user feedback</string>
     <!-- Description for enabling to send user statistics to Google -->
     <string name="prefs_description_log">Help improve this input method editor by automatically sending usage statistics and crash reports to Google.</string>
-    <!-- Preferences item for enabling to correct suggestions by touching words you have typed [CHAR LIMIT= 35] -->
-    <string name="prefs_enable_recorrection">Touch to correct words</string>
-    <!-- The summary for the preferences item for enabling to correct suggestions by touching words you have typed [CHAR LIMIT= 100] -->
-    <string name="prefs_enable_recorrection_summary">Touch entered words to correct them, only when suggestions are visible</string>
 
     <!-- Title of the item to change the keyboard theme [CHAR LIMIT=20]-->
     <string name="keyboard_layout">Keyboard theme</string>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 312af28..b54df26 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -45,12 +45,6 @@
             android:persistent="true"
             android:defaultValue="@bool/config_default_popup_preview" />
         <CheckBoxPreference
-            android:key="recorrection_enabled"
-            android:title="@string/prefs_enable_recorrection"
-            android:summary="@string/prefs_enable_recorrection_summary"
-            android:persistent="true"
-            android:defaultValue="@bool/config_default_compat_recorrection_enabled" />
-        <CheckBoxPreference
             android:key="show_settings_key"
             android:title="@string/prefs_settings_key"
             android:persistent="true"
diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
deleted file mode 100644
index 94615a7..0000000
--- a/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.deprecated.recorrection;
-
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
-import android.view.inputmethod.InputConnection;
-
-import com.android.inputmethod.compat.InputConnectionCompatUtils;
-import com.android.inputmethod.compat.SuggestionSpanUtils;
-import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.latin.AutoCorrection;
-import com.android.inputmethod.latin.EditingUtils;
-import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Settings;
-import com.android.inputmethod.latin.Suggest;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestionsView;
-import com.android.inputmethod.latin.TextEntryState;
-import com.android.inputmethod.latin.WordComposer;
-
-import java.util.ArrayList;
-
-/**
- * Manager of re-correction functionalities
- */
-public class Recorrection implements SharedPreferences.OnSharedPreferenceChangeListener {
-    private static final Recorrection sInstance = new Recorrection();
-
-    private LatinIME mService;
-    private boolean mRecorrectionEnabled = false;
-    private final ArrayList<RecorrectionSuggestionEntries> mRecorrectionSuggestionsList =
-            new ArrayList<RecorrectionSuggestionEntries>();
-
-    public static Recorrection getInstance() {
-        return sInstance;
-    }
-
-    public static void init(LatinIME context, SharedPreferences prefs) {
-        if (context == null || prefs == null) {
-            return;
-        }
-        sInstance.initInternal(context, prefs);
-    }
-
-    private Recorrection() {
-    }
-
-    public boolean isRecorrectionEnabled() {
-        return mRecorrectionEnabled;
-    }
-
-    private void initInternal(LatinIME context, SharedPreferences prefs) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) {
-            mRecorrectionEnabled = false;
-            return;
-        }
-        updateRecorrectionEnabled(context.getResources(), prefs);
-        mService = context;
-        prefs.registerOnSharedPreferenceChangeListener(this);
-    }
-
-    public void checkRecorrectionOnStart() {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
-
-        final InputConnection ic = mService.getCurrentInputConnection();
-        if (ic == null) return;
-        // There could be a pending composing span.  Clean it up first.
-        ic.finishComposingText();
-
-        if (mService.isShowingSuggestionsStrip() && mService.isSuggestionsRequested()) {
-            // First get the cursor position. This is required by setOldSuggestions(), so that
-            // it can pass the correct range to setComposingRegion(). At this point, we don't
-            // have valid values for mLastSelectionStart/End because onUpdateSelection() has
-            // not been called yet.
-            ExtractedTextRequest etr = new ExtractedTextRequest();
-            etr.token = 0; // anything is fine here
-            ExtractedText et = ic.getExtractedText(etr, 0);
-            if (et == null) return;
-            mService.setLastSelection(
-                    et.startOffset + et.selectionStart, et.startOffset + et.selectionEnd);
-
-            // Then look for possible corrections in a delayed fashion
-            if (!TextUtils.isEmpty(et.text) && mService.isCursorTouchingWord()) {
-                mService.mHandler.postUpdateOldSuggestions();
-            }
-        }
-    }
-
-    public void updateRecorrectionSelection(KeyboardSwitcher keyboardSwitcher,
-            SuggestionsView suggestionsView, int candidatesStart, int candidatesEnd,
-            int newSelStart, int newSelEnd, int oldSelStart, int lastSelectionStart,
-            int lastSelectionEnd, boolean hasUncommittedTypedChars) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
-        if (!mService.isShowingSuggestionsStrip()) return;
-        if (!keyboardSwitcher.isInputViewShown()) return;
-        if (!mService.isSuggestionsRequested()) return;
-        // Don't look for corrections if the keyboard is not visible
-        // Check if we should go in or out of correction mode.
-        if ((candidatesStart == candidatesEnd || newSelStart != oldSelStart || TextEntryState
-                .isRecorrecting())
-                && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) {
-            if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) {
-                mService.mHandler.cancelUpdateBigramPredictions();
-                mService.mHandler.postUpdateOldSuggestions();
-            } else {
-                abortRecorrection(false);
-                // If showing the "touch again to save" hint, do not replace it. Else,
-                // show the bigrams if we are at the end of the text, punctuation
-                // otherwise.
-                if (suggestionsView != null && !suggestionsView.isShowingAddToDictionaryHint()) {
-                    InputConnection ic = mService.getCurrentInputConnection();
-                    if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) {
-                        if (!mService.isShowingPunctuationList()) {
-                            mService.setPunctuationSuggestions();
-                        }
-                    } else {
-                        mService.mHandler.postUpdateBigramPredictions();
-                    }
-                }
-            }
-        }
-    }
-
-    public void saveRecorrectionSuggestion(WordComposer word, CharSequence result) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
-        if (word.size() <= 1) {
-            return;
-        }
-        // Skip if result is null. It happens in some edge case.
-        if (TextUtils.isEmpty(result)) {
-            return;
-        }
-
-        // Make a copy of the CharSequence, since it is/could be a mutable CharSequence
-        final String resultCopy = result.toString();
-        RecorrectionSuggestionEntries entry = new RecorrectionSuggestionEntries(
-                resultCopy, new WordComposer(word));
-        mRecorrectionSuggestionsList.add(entry);
-    }
-
-    public void clearWordsInHistory() {
-        mRecorrectionSuggestionsList.clear();
-    }
-
-    /**
-     * Tries to apply any typed alternatives for the word if we have any cached alternatives,
-     * otherwise tries to find new corrections and completions for the word.
-     * @param touching The word that the cursor is touching, with position information
-     * @return true if an alternative was found, false otherwise.
-     */
-    public boolean applyTypedAlternatives(WordComposer word, Suggest suggest,
-            KeyboardSwitcher keyboardSwitcher, EditingUtils.SelectedWord touching) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return false;
-        // If we didn't find a match, search for result in typed word history
-        WordComposer foundWord = null;
-        RecorrectionSuggestionEntries alternatives = null;
-        // Search old suggestions to suggest re-corrected suggestions.
-        for (RecorrectionSuggestionEntries entry : mRecorrectionSuggestionsList) {
-            if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
-                foundWord = entry.mWordComposer;
-                alternatives = entry;
-                break;
-            }
-        }
-        // If we didn't find a match, at least suggest corrections as re-corrected suggestions.
-        if (foundWord == null
-                && (AutoCorrection.isValidWord(suggest.getUnigramDictionaries(),
-                        touching.mWord, true))) {
-            foundWord = new WordComposer();
-            for (int i = 0; i < touching.mWord.length(); i++) {
-                foundWord.add(touching.mWord.charAt(i),
-                        new int[] { touching.mWord.charAt(i) }, WordComposer.NOT_A_COORDINATE,
-                        WordComposer.NOT_A_COORDINATE);
-            }
-        }
-        // Found a match, show suggestions
-        if (foundWord != null || alternatives != null) {
-            if (alternatives == null) {
-                alternatives = new RecorrectionSuggestionEntries(touching.mWord, foundWord);
-            }
-            showRecorrections(suggest, keyboardSwitcher, alternatives);
-            if (foundWord != null) {
-                word.init(foundWord);
-            } else {
-                word.reset();
-            }
-            return true;
-        }
-        return false;
-    }
-
-
-    private void showRecorrections(Suggest suggest, KeyboardSwitcher keyboardSwitcher,
-            RecorrectionSuggestionEntries entries) {
-        SuggestedWords.Builder builder = entries.getAlternatives(suggest, keyboardSwitcher);
-        builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
-        mService.showSuggestions(builder.build(), entries.getOriginalWord());
-    }
-
-    public void fetchAndDisplayRecorrectionSuggestions(VoiceProxy voiceProxy,
-            SuggestionsView suggestionsView, Suggest suggest, KeyboardSwitcher keyboardSwitcher,
-            WordComposer word, boolean hasUncommittedTypedChars, int lastSelectionStart,
-            int lastSelectionEnd, String wordSeparators) {
-        if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return;
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
-        voiceProxy.setShowingVoiceSuggestions(false);
-        if (suggestionsView != null && suggestionsView.isShowingAddToDictionaryHint()) {
-            return;
-        }
-        InputConnection ic = mService.getCurrentInputConnection();
-        if (ic == null) return;
-        if (!hasUncommittedTypedChars) {
-            // Extract the selected or touching text
-            EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic,
-                    lastSelectionStart, lastSelectionEnd, wordSeparators);
-
-            if (touching != null && touching.mWord.length() > 1) {
-                ic.beginBatchEdit();
-
-                if (applyTypedAlternatives(word, suggest, keyboardSwitcher, touching)
-                        || voiceProxy.applyVoiceAlternatives(touching)) {
-                    TextEntryState.selectedForRecorrection();
-                    InputConnectionCompatUtils.underlineWord(ic, touching);
-                } else {
-                    abortRecorrection(true);
-                }
-
-                ic.endBatchEdit();
-            } else {
-                abortRecorrection(true);
-                mService.updateBigramPredictions();
-            }
-        } else {
-            abortRecorrection(true);
-        }
-    }
-
-    public void abortRecorrection(boolean force) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
-        if (force || TextEntryState.isRecorrecting()) {
-            TextEntryState.onAbortRecorrection();
-            mService.setCandidatesViewShown(mService.isSuggestionsStripVisible());
-            mService.getCurrentInputConnection().finishComposingText();
-            mService.clearSuggestions();
-        }
-    }
-
-    public void updateRecorrectionEnabled(Resources res, SharedPreferences prefs) {
-        // If the option should not be shown, do not read the re-correction preference
-        // but always use the default setting defined in the resources.
-        if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
-            mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
-                    res.getBoolean(R.bool.config_default_compat_recorrection_enabled));
-        } else {
-            mRecorrectionEnabled =
-                    res.getBoolean(R.bool.config_default_compat_recorrection_enabled);
-        }
-    }
-
-    @Override
-    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
-        if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
-        if (key.equals(Settings.PREF_RECORRECTION_ENABLED)) {
-            updateRecorrectionEnabled(mService.getResources(), prefs);
-        }
-    }
-}
diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
deleted file mode 100644
index 36ffe2d..0000000
--- a/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.deprecated.recorrection;
-
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.latin.Suggest;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.WordComposer;
-
-import android.text.TextUtils;
-
-public class RecorrectionSuggestionEntries {
-    public final CharSequence mChosenWord;
-    public final WordComposer mWordComposer;
-
-    public RecorrectionSuggestionEntries(CharSequence chosenWord, WordComposer wordComposer) {
-        mChosenWord = chosenWord;
-        mWordComposer = wordComposer;
-    }
-
-    public CharSequence getChosenWord() {
-        return mChosenWord;
-    }
-
-    public CharSequence getOriginalWord() {
-        return mWordComposer.getTypedWord();
-    }
-
-    public SuggestedWords.Builder getAlternatives(
-            Suggest suggest, KeyboardSwitcher keyboardSwitcher) {
-        return getTypedSuggestions(suggest, keyboardSwitcher, mWordComposer);
-    }
-
-    @Override
-    public int hashCode() {
-        return mChosenWord.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof CharSequence && TextUtils.equals(mChosenWord, (CharSequence)o);
-    }
-
-    private static SuggestedWords.Builder getTypedSuggestions(
-            Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word) {
-        return suggest.getSuggestedWordBuilder(word, null,
-                keyboardSwitcher.getLatinKeyboard().getProximityInfo());
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index ec35872..e723dc1 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -259,9 +259,10 @@
         params.mTouchPositionCorrectionRadii = null;
 
         final TypedArray a = context.obtainStyledAttributes(
-                null, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard);
+                null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
         params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
         final int resourceId = a.getResourceId(R.styleable.Keyboard_touchPositionCorrectionData, 0);
+        a.recycle();
         if (resourceId == 0) {
             if (LatinImeLogger.sDBG)
                 throw new RuntimeException("touchPositionCorrectionData is not defined");
@@ -269,7 +270,6 @@
         }
 
         final String[] data = context.getResources().getStringArray(resourceId);
-        a.recycle();
         final int dataLength = data.length;
         if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
             if (LatinImeLogger.sDBG)
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 777881c..036873c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -60,7 +60,6 @@
 import com.android.inputmethod.compat.VibratorCompatWrapper;
 import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
 import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.deprecated.recorrection.Recorrection;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardActionListener;
@@ -168,7 +167,6 @@
     private KeyboardSwitcher mKeyboardSwitcher;
     private SubtypeSwitcher mSubtypeSwitcher;
     private VoiceProxy mVoiceProxy;
-    private Recorrection mRecorrection;
 
     private UserDictionary mUserDictionary;
     private UserBigramDictionary mUserBigramDictionary;
@@ -229,14 +227,13 @@
 
     public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> {
         private static final int MSG_UPDATE_SUGGESTIONS = 0;
-        private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1;
-        private static final int MSG_UPDATE_SHIFT_STATE = 2;
-        private static final int MSG_VOICE_RESULTS = 3;
-        private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4;
-        private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5;
-        private static final int MSG_SPACE_TYPED = 6;
-        private static final int MSG_SET_BIGRAM_PREDICTIONS = 7;
-        private static final int MSG_PENDING_IMS_CALLBACK = 8;
+        private static final int MSG_UPDATE_SHIFT_STATE = 1;
+        private static final int MSG_VOICE_RESULTS = 2;
+        private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 3;
+        private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 4;
+        private static final int MSG_SPACE_TYPED = 5;
+        private static final int MSG_SET_BIGRAM_PREDICTIONS = 6;
+        private static final int MSG_PENDING_IMS_CALLBACK = 7;
 
         public UIHandler(LatinIME outerInstance) {
             super(outerInstance);
@@ -251,13 +248,6 @@
             case MSG_UPDATE_SUGGESTIONS:
                 latinIme.updateSuggestions();
                 break;
-            case MSG_UPDATE_OLD_SUGGESTIONS:
-                latinIme.mRecorrection.fetchAndDisplayRecorrectionSuggestions(
-                        latinIme.mVoiceProxy, latinIme.mSuggestionsView,
-                        latinIme.mSuggest, latinIme.mKeyboardSwitcher, latinIme.mWordComposer,
-                        latinIme.mHasUncommittedTypedChars, latinIme.mLastSelectionStart,
-                        latinIme.mLastSelectionEnd, latinIme.mSettingsValues.mWordSeparators);
-                break;
             case MSG_UPDATE_SHIFT_STATE:
                 switcher.updateShiftState();
                 break;
@@ -302,16 +292,6 @@
             return hasMessages(MSG_UPDATE_SUGGESTIONS);
         }
 
-        public void postUpdateOldSuggestions() {
-            removeMessages(MSG_UPDATE_OLD_SUGGESTIONS);
-            sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS),
-                    getOuterInstance().mSettingsValues.mDelayUpdateOldSuggestions);
-        }
-
-        public void cancelUpdateOldSuggestions() {
-            removeMessages(MSG_UPDATE_OLD_SUGGESTIONS);
-        }
-
         public void postUpdateShiftKeyState() {
             removeMessages(MSG_UPDATE_SHIFT_STATE);
             sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE),
@@ -470,7 +450,6 @@
         InputMethodManagerCompatWrapper.init(this);
         SubtypeSwitcher.init(this);
         KeyboardSwitcher.init(this, prefs);
-        Recorrection.init(this, prefs);
         AccessibilityUtils.init(this, prefs);
 
         super.onCreate();
@@ -479,7 +458,6 @@
         mInputMethodId = Utils.getInputMethodId(mImm, getPackageName());
         mSubtypeSwitcher = SubtypeSwitcher.getInstance();
         mKeyboardSwitcher = KeyboardSwitcher.getInstance();
-        mRecorrection = Recorrection.getInstance();
         mVibrator = VibratorCompatWrapper.getInstance(this);
         DEBUG = LatinImeLogger.sDBG;
 
@@ -758,8 +736,6 @@
         inputView.setKeyPreviewPopupEnabled(mSettingsValues.mKeyPreviewPopupOn,
                 mSettingsValues.mKeyPreviewPopupDismissDelay);
         inputView.setProximityCorrectionEnabled(true);
-        // If we just entered a text field, maybe it has some old text that requires correction
-        mRecorrection.checkRecorrectionOnStart();
 
         voiceIme.onStartInputView(inputView.getWindowToken());
 
@@ -848,7 +824,6 @@
         if (inputView != null) inputView.cancelAllMessages();
         // Remove pending messages related to update suggestions
         mHandler.cancelUpdateSuggestions();
-        mHandler.cancelUpdateOldSuggestions();
     }
 
     @Override
@@ -882,35 +857,23 @@
         final boolean selectionChanged = (newSelStart != candidatesEnd
                 || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart;
         final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1;
-        if (!mExpectingUpdateSelection
-                && ((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
-                || mVoiceProxy.isVoiceInputHighlighted())
-                && (selectionChanged || candidatesCleared)) {
-            if (candidatesCleared) {
-                // If the composing span has been cleared, save the typed word in the history for
-                // recorrection before we reset the suggestions strip.  Then, we'll be able to show
-                // suggestions for recorrection right away.
-                mRecorrection.saveRecorrectionSuggestion(mWordComposer, mComposingStringBuilder);
-            }
-            mComposingStringBuilder.setLength(0);
-            mHasUncommittedTypedChars = false;
-            if (isCursorTouchingWord()) {
-                mHandler.cancelUpdateBigramPredictions();
-                mHandler.postUpdateSuggestions();
-            } else {
-                setPunctuationSuggestions();
-            }
-            TextEntryState.reset();
-            final InputConnection ic = getCurrentInputConnection();
-            if (ic != null) {
-                ic.finishComposingText();
-            }
-            mVoiceProxy.setVoiceInputHighlighted(false);
-        } else if (!mHasUncommittedTypedChars && !mExpectingUpdateSelection
-                && TextEntryState.isAcceptedDefault()) {
-            TextEntryState.reset();
-        }
         if (!mExpectingUpdateSelection) {
+            if (((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
+                    || mVoiceProxy.isVoiceInputHighlighted())
+                    && (selectionChanged || candidatesCleared)) {
+                mComposingStringBuilder.setLength(0);
+                mHasUncommittedTypedChars = false;
+                TextEntryState.reset();
+                updateSuggestions();
+                final InputConnection ic = getCurrentInputConnection();
+                if (ic != null) {
+                    ic.finishComposingText();
+                }
+                mVoiceProxy.setVoiceInputHighlighted(false);
+            } else if (!mHasUncommittedTypedChars) {
+                TextEntryState.reset();
+                updateSuggestions();
+            }
             mJustAddedMagicSpace = false; // The user moved the cursor.
             mJustReplacedDoubleSpace = false;
         }
@@ -920,11 +883,6 @@
         // Make a note of the cursor position
         mLastSelectionStart = newSelStart;
         mLastSelectionEnd = newSelEnd;
-
-        mRecorrection.updateRecorrectionSelection(mKeyboardSwitcher,
-                mSuggestionsView, candidatesStart, candidatesEnd, newSelStart,
-                newSelEnd, oldSelStart, mLastSelectionStart,
-                mLastSelectionEnd, mHasUncommittedTypedChars);
     }
 
     public void setLastSelection(int start, int end) {
@@ -942,7 +900,7 @@
      */
     @Override
     public void onExtractedTextClicked() {
-        if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return;
+        if (isSuggestionsRequested()) return;
 
         super.onExtractedTextClicked();
     }
@@ -958,7 +916,7 @@
      */
     @Override
     public void onExtractedCursorMovement(int dx, int dy) {
-        if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return;
+        if (isSuggestionsRequested()) return;
 
         super.onExtractedCursorMovement(dx, dy);
     }
@@ -974,7 +932,6 @@
             mOptionsDialog = null;
         }
         mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
-        mRecorrection.clearWordsInHistory();
         super.hideWindow();
     }
 
@@ -1330,7 +1287,6 @@
         mVoiceProxy.commitVoiceInput();
         final InputConnection ic = getCurrentInputConnection();
         if (ic == null) return;
-        mRecorrection.abortRecorrection(false);
         ic.beginBatchEdit();
         commitTyped(ic);
         maybeRemovePreviousPeriod(ic, text);
@@ -1446,17 +1402,12 @@
             removeTrailingSpace();
         }
 
-        if (mLastSelectionStart == mLastSelectionEnd) {
-            mRecorrection.abortRecorrection(false);
-        }
-
         int code = primaryCode;
         if ((isAlphabet(code) || mSettingsValues.isSymbolExcludedFromWordSeparators(code))
                 && isSuggestionsRequested() && !isCursorTouchingWord()) {
             if (!mHasUncommittedTypedChars) {
                 mHasUncommittedTypedChars = true;
                 mComposingStringBuilder.setLength(0);
-                mRecorrection.saveRecorrectionSuggestion(mWordComposer, mBestWord);
                 mWordComposer.reset();
                 clearSuggestions();
             }
@@ -1522,7 +1473,6 @@
         final InputConnection ic = getCurrentInputConnection();
         if (ic != null) {
             ic.beginBatchEdit();
-            mRecorrection.abortRecorrection(false);
         }
         if (mHasUncommittedTypedChars) {
             // In certain languages where single quote is a separator, it's better
@@ -1568,7 +1518,6 @@
         if (Keyboard.CODE_SPACE == primaryCode) {
             if (!isCursorTouchingWord()) {
                 mHandler.cancelUpdateSuggestions();
-                mHandler.cancelUpdateOldSuggestions();
                 mHandler.postUpdateBigramPredictions();
             }
         } else {
@@ -1655,6 +1604,9 @@
             return;
         }
 
+        mHandler.cancelUpdateSuggestions();
+        mHandler.cancelUpdateBigramPredictions();
+
         if (!mHasUncommittedTypedChars) {
             setPunctuationSuggestions();
             return;
@@ -1887,7 +1839,6 @@
                 ic.commitText(bestWord, 1);
             }
         }
-        mRecorrection.saveRecorrectionSuggestion(mWordComposer, bestWord);
         mHasUncommittedTypedChars = false;
         mCommittedLength = bestWord.length();
     }
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index bd94bab..d9508f4 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -64,7 +64,6 @@
     public static final String PREF_VIBRATE_ON = "vibrate_on";
     public static final String PREF_SOUND_ON = "sound_on";
     public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on";
-    public static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled";
     public static final String PREF_AUTO_CAP = "auto_cap";
     public static final String PREF_SHOW_SETTINGS_KEY = "show_settings_key";
     public static final String PREF_VOICE_SETTINGS_KEY = "voice_mode";
@@ -435,12 +434,6 @@
             generalSettings.removePreference(findPreference(PREF_KEY_PREVIEW_POPUP_ON));
         }
 
-        final boolean showRecorrectionOption = res.getBoolean(
-                R.bool.config_enable_show_recorrection_option);
-        if (!showRecorrectionOption) {
-            generalSettings.removePreference(findPreference(PREF_RECORRECTION_ENABLED));
-        }
-
         final boolean showBigramSuggestionsOption = res.getBoolean(
                 R.bool.config_enable_bigram_suggestions_option);
         if (!showBigramSuggestionsOption) {
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index 081cb61..547d5e8 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -224,7 +224,7 @@
         return UNKNOWN;
     }
     const float sweetSpotCenterX = mSweetSpotCenterXs[keyIndex];
-    const float sweetSpotCenterY = mSweetSpotCenterXs[keyIndex];
+    const float sweetSpotCenterY = mSweetSpotCenterYs[keyIndex];
     const float inputX = (float)mInputXCoordinates[index];
     const float inputY = (float)mInputYCoordinates[index];
     const float squaredDistance =