diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
new file mode 100644
index 0000000..d1154d9
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -0,0 +1,103 @@
+/*
+ * 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.latin;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class AutoCorrection {
+    private static final boolean DBG = LatinImeLogger.sDBG;
+    private static final String TAG = AutoCorrection.class.getSimpleName();
+    private boolean mHasAutoCorrection;
+    private CharSequence mAutoCorrectionWord;
+    private double mNormalizedScore;
+
+    public void init() {
+        mHasAutoCorrection = false;
+        mAutoCorrectionWord = null;
+        mNormalizedScore = Integer.MIN_VALUE;
+    }
+
+    public boolean hasAutoCorrection() {
+        return mHasAutoCorrection;
+    }
+
+    public CharSequence getAutoCorrectionWord() {
+        return mAutoCorrectionWord;
+    }
+
+    public double getNormalizedScore() {
+        return mNormalizedScore;
+    }
+
+    public void updateAutoCorrectionStatus(Suggest suggest,
+            WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] priorities,
+            CharSequence typedWord, double autoCorrectionThreshold, int correctionMode,
+            CharSequence quickFixedWord) {
+        if (hasAutoCorrectionForTypedWord(
+                suggest, wordComposer, suggestions, typedWord, correctionMode)) {
+            mHasAutoCorrection = true;
+            mAutoCorrectionWord = typedWord;
+        } else if (hasAutoCorrectForBinaryDictionary(wordComposer, suggestions, correctionMode,
+                priorities, typedWord, autoCorrectionThreshold)) {
+            mHasAutoCorrection = true;
+            mAutoCorrectionWord = suggestions.get(0);
+        } else if (hasAutoCorrectionForQuickFix(quickFixedWord)) {
+            mHasAutoCorrection = true;
+            mAutoCorrectionWord = quickFixedWord;
+        }
+    }
+
+    private boolean hasAutoCorrectionForTypedWord(Suggest suggest, WordComposer wordComposer,
+            ArrayList<CharSequence> suggestions, CharSequence typedWord, int correctionMode) {
+        return wordComposer.size() > 1 && suggestions.size() > 0 && suggest.isValidWord(typedWord)
+                && (correctionMode == Suggest.CORRECTION_FULL
+                || correctionMode == Suggest.CORRECTION_FULL_BIGRAM);
+    }
+
+    private boolean hasAutoCorrectForBinaryDictionary(WordComposer wordComposer,
+            ArrayList<CharSequence> suggestions, int correctionMode, int[] priorities,
+            CharSequence typedWord, double autoCorrectionThreshold) {
+        if (wordComposer.size() > 1 && (correctionMode == Suggest.CORRECTION_FULL
+                || correctionMode == Suggest.CORRECTION_FULL_BIGRAM)
+                && typedWord != null && suggestions.size() > 0 && priorities.length > 0) {
+            final CharSequence autoCorrectionCandidate = suggestions.get(0);
+            final int autoCorrectionCandidateScore = priorities[0];
+            // TODO: when the normalized score of the first suggestion is nearly equals to
+            //       the normalized score of the second suggestion, behave less aggressive.
+            mNormalizedScore = Utils.calcNormalizedScore(
+                    typedWord,autoCorrectionCandidate, autoCorrectionCandidateScore);
+            if (DBG) {
+                Log.d(TAG, "Normalized " + typedWord + "," + autoCorrectionCandidate + ","
+                        + autoCorrectionCandidateScore + ", " + mNormalizedScore
+                        + "(" + autoCorrectionThreshold + ")");
+            }
+            if (mNormalizedScore >= autoCorrectionThreshold) {
+                if (DBG) {
+                    Log.d(TAG, "Auto corrected by S-threshold.");
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean hasAutoCorrectionForQuickFix(CharSequence quickFixedWord) {
+        return quickFixedWord != null;
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index feaebb9..646de66 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1530,7 +1530,7 @@
     }
 
     private void showSuggestions(WordComposer word) {
-        // TODO Maybe need better way of retrieving previous word
+        // TODO: May need a better way of retrieving previous word
         CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
                 mWordSeparators);
         SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
@@ -2052,6 +2052,7 @@
     }
 
     private void updateCorrectionMode() {
+        // TODO: cleanup messy flags
         mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
         mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
                 && !mInputTypeNoAutoCorrect && mHasDictionary;
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index ee6930d..95a2d63 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -67,6 +67,8 @@
 
     private static final boolean DBG = LatinImeLogger.sDBG;
 
+    private AutoCorrection mAutoCorrection;
+
     private BinaryDictionary mMainDict;
 
     private Dictionary mUserDictionary;
@@ -90,7 +92,6 @@
     private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
     ArrayList<CharSequence> mBigramSuggestions  = new ArrayList<CharSequence>();
     private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
-    private boolean mHasAutoCorrection;
     private String mLowerOriginalWord;
 
     // TODO: Remove these member variables by passing more context to addWord() callback method
@@ -101,12 +102,16 @@
 
     public Suggest(Context context, int dictionaryResId) {
         mMainDict = BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN);
-        initPool();
+        init();
     }
 
-    // For unit test
-    /* package */ Suggest(File dictionary, long startOffset, long length) {
+    /* package for test */ Suggest(File dictionary, long startOffset, long length) {
         mMainDict = BinaryDictionary.initDictionary(dictionary, startOffset, length, DIC_MAIN);
+        init();
+    }
+
+    private void init() {
+        mAutoCorrection = new AutoCorrection();
         initPool();
     }
 
@@ -205,7 +210,7 @@
     public SuggestedWords.Builder getSuggestedWordBuilder(View view, WordComposer wordComposer,
             CharSequence prevWordForBigram) {
         LatinImeLogger.onStartSuggestion(prevWordForBigram);
-        mHasAutoCorrection = false;
+        mAutoCorrection.init();
         mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
         mIsAllUpperCase = wordComposer.isAllUpperCase();
         collectGarbage(mSuggestions, mPrefMaxSuggestions);
@@ -224,7 +229,6 @@
             mLowerOriginalWord = "";
         }
 
-        double normalizedScore = Integer.MIN_VALUE;
         if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
                 || mCorrectionMode == CORRECTION_BASIC)) {
             // At first character typed, search only the bigrams
@@ -273,86 +277,67 @@
                 if (mContactsDictionary != null) {
                     mContactsDictionary.getWords(wordComposer, this);
                 }
-
-                if (mSuggestions.size() > 0 && isValidWord(typedWord)
-                        && (mCorrectionMode == CORRECTION_FULL
-                        || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
-                    if (DBG) {
-                        Log.d(TAG, "Auto corrected by CORRECTION_FULL.");
-                    }
-                    mHasAutoCorrection = true;
-                }
             }
             if (mMainDict != null) mMainDict.getWords(wordComposer, this);
-            if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
-                    && mSuggestions.size() > 0 && mPriorities.length > 0) {
-                // TODO: when the normalized score of the first suggestion is nearly equals to
-                //       the normalized score of the second suggestion, behave less aggressive.
-                normalizedScore = Utils.calcNormalizedScore(
-                        typedWord, mSuggestions.get(0), mPriorities[0]);
-                if (DBG) {
-                    Log.d(TAG, "Normalized " + typedWord + "," + mSuggestions.get(0) + ","
-                            + mPriorities[0] + ", " + normalizedScore
-                            + "(" + mAutoCorrectionThreshold + ")");
-                }
-                if (normalizedScore >= mAutoCorrectionThreshold) {
-                    if (DBG) {
-                        Log.d(TAG, "Auto corrected by S-threshold.");
-                    }
-                    mHasAutoCorrection = true;
-                }
-            }
         }
+        CharSequence autoText = null;
+        final String typedWordString = typedWord == null ? null : typedWord.toString();
         if (typedWord != null) {
-            mSuggestions.add(0, typedWord.toString());
-        }
-        if (mQuickFixesEnabled) {
-            int i = 0;
-            int max = 6;
-            // Don't autotext the suggestions from the dictionaries
-            if (mCorrectionMode == CORRECTION_BASIC) max = 1;
-            while (i < mSuggestions.size() && i < max) {
-                String suggestedWord = mSuggestions.get(i).toString().toLowerCase();
-                CharSequence autoText =
-                        AutoText.get(suggestedWord, 0, suggestedWord.length(), view);
+            // Apply quick fix only for the typed word.
+            if (mQuickFixesEnabled) {
+                final String lowerCaseTypedWord = typedWordString.toLowerCase();
+                CharSequence tempAutoText =
+                        AutoText.get(lowerCaseTypedWord, 0, lowerCaseTypedWord.length(), view);
                 // Is there an AutoText (also known as Quick Fixes) correction?
-                boolean canAdd = autoText != null;
                 // Capitalize as needed
-                final int autoTextLength = autoText != null ? autoText.length() : 0;
-                if (autoTextLength > 0 && (mIsAllUpperCase || mIsFirstCharCapitalized)) {
-                    int poolSize = mStringPool.size();
-                    StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(
-                            poolSize - 1) : new StringBuilder(getApproxMaxWordLength());
+                if (!TextUtils.isEmpty(tempAutoText)
+                        && (mIsAllUpperCase || mIsFirstCharCapitalized)) {
+                    final int tempAutoTextLength = tempAutoText.length();
+                    final int poolSize = mStringPool.size();
+                    final StringBuilder sb =
+                            poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1)
+                                    : new StringBuilder(getApproxMaxWordLength());
                     sb.setLength(0);
                     if (mIsAllUpperCase) {
-                        sb.append(autoText.toString().toUpperCase());
+                        sb.append(tempAutoText.toString().toUpperCase());
                     } else if (mIsFirstCharCapitalized) {
-                        sb.append(Character.toUpperCase(autoText.charAt(0)));
-                        if (autoTextLength > 1) {
-                            sb.append(autoText.subSequence(1, autoTextLength));
+                        sb.append(Character.toUpperCase(tempAutoText.charAt(0)));
+                        if (tempAutoTextLength > 1) {
+                            sb.append(tempAutoText.subSequence(1, tempAutoTextLength));
                         }
                     }
-                    autoText = sb.toString();
+                    tempAutoText = sb.toString();
                 }
+                boolean canAdd = tempAutoText != null;
                 // Is that correction already the current prediction (or original word)?
-                canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i));
+                canAdd &= !TextUtils.equals(tempAutoText, typedWord);
                 // Is that correction already the next predicted word?
-                if (canAdd && i + 1 < mSuggestions.size() && mCorrectionMode != CORRECTION_BASIC) {
-                    canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
+                if (canAdd && mSuggestions.size() > 0 && mCorrectionMode != CORRECTION_BASIC) {
+                    canAdd &= !TextUtils.equals(tempAutoText, mSuggestions.get(0));
                 }
                 if (canAdd) {
                     if (DBG) {
                         Log.d(TAG, "Auto corrected by AUTOTEXT.");
                     }
-                    mHasAutoCorrection = true;
-                    mSuggestions.add(i + 1, autoText);
-                    i++;
+                    autoText = tempAutoText;
                 }
-                i++;
             }
         }
+
+        mAutoCorrection.updateAutoCorrectionStatus(this, wordComposer, mSuggestions, mPriorities,
+                typedWord, mAutoCorrectionThreshold, mCorrectionMode, autoText);
+
+        if (autoText != null) {
+            mSuggestions.add(0, autoText);
+        }
+
+        if (typedWord != null) {
+            mSuggestions.add(0, typedWordString);
+        }
         removeDupes();
+
         if (DBG) {
+            double normalizedScore = mAutoCorrection.getNormalizedScore();
             ArrayList<SuggestedWords.SuggestedWordInfo> frequencyInfoList =
                     new ArrayList<SuggestedWords.SuggestedWordInfo>();
             frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false));
@@ -373,9 +358,8 @@
                 frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false));
             }
             return new SuggestedWords.Builder().addWords(mSuggestions, frequencyInfoList);
-        } else {
-            return new SuggestedWords.Builder().addWords(mSuggestions, null);
         }
+        return new SuggestedWords.Builder().addWords(mSuggestions, null);
     }
 
     private void removeDupes() {
@@ -406,7 +390,7 @@
     }
 
     public boolean hasAutoCorrection() {
-        return mHasAutoCorrection;
+        return mAutoCorrection.hasAutoCorrection();
     }
 
     private static boolean compareCaseInsensitive(final String lowerOriginalWord,
