diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index 3f47ea3709acf6014b56345a22a7ee681b72ef79..30f4a59f95b8650b7e1f95633656b08a56b50aed 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -82,7 +82,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
                 hidePreview();
                 break;
             case MSG_UPDATE_SUGGESTION:
-                updateSuggestions((SuggestedWords)msg.obj);
+                updateSuggestions();
                 break;
             }
         }
@@ -96,9 +96,9 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
             removeMessages(MSG_HIDE_PREVIEW);
         }
 
-        public void postUpdateSuggestions(SuggestedWords suggestions) {
+        public void postUpdateSuggestions() {
             cancelUpdateSuggestions();
-            sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION, suggestions),
+            sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION),
                     DELAY_UPDATE_SUGGESTION);
         }
 
@@ -162,20 +162,19 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     }
 
     public void setSuggestions(SuggestedWords suggestions) {
-        // Don't update suggestions when there is only one suggestion found.
-        // Empty (size zero) suggestions will be passed in order to clear candidate view.
-        if (suggestions == null || suggestions.size() == 1)
+        if (suggestions == null)
             return;
+        mSuggestions = suggestions;
         if (mShowingAutoCorrectionInverted) {
-            mHandler.postUpdateSuggestions(suggestions);
+            mHandler.postUpdateSuggestions();
         } else {
-            updateSuggestions(suggestions);
+            updateSuggestions();
         }
     }
 
-    private void updateSuggestions(SuggestedWords suggestions) {
+    private void updateSuggestions() {
+        final SuggestedWords suggestions = mSuggestions;
         clear();
-        mSuggestions = suggestions;
         final int count = suggestions.size();
         final Object[] debugInfo = suggestions.mDebugInfo;
         for (int i = 0; i < count; i++) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9a240cb418f4ab4b46443ae5a352c559b8e5c640..e9f200a8b35bd214b365b03d6d7d466ef8948faf 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -140,8 +140,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     private final StringBuilder mComposing = new StringBuilder();
     private WordComposer mWord = new WordComposer();
     private CharSequence mBestWord;
-    private boolean mPredicting;
-    private boolean mPredictionOn;
+    private boolean mHasValidSuggestions;
+    private boolean mIsSettingsSuggestionStripOn;
     private boolean mApplicationSpecifiedCompletionOn;
     private boolean mHasDictionary;
     private boolean mAutoSpace;
@@ -519,7 +519,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION;
         mVoiceConnector.resetVoiceStates(isPasswordVariation(variation));
         mInputTypeNoAutoCorrect = false;
-        mPredictionOn = false;
+        mIsSettingsSuggestionStripOn = false;
         mApplicationSpecifiedCompletionOn = false;
         mApplicationSpecifiedCompletions = null;
         mEnteredText = null;
@@ -534,11 +534,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                 mode = KeyboardId.MODE_PHONE;
                 break;
             case InputType.TYPE_CLASS_TEXT:
-                //startPrediction();
-                mPredictionOn = true;
+                mIsSettingsSuggestionStripOn = true;
                 // Make sure that passwords are not displayed in candidate view
                 if (isPasswordVariation(variation)) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                 }
                 if (isEmailVariation(variation)
                         || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
@@ -547,15 +546,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     mAutoSpace = true;
                 }
                 if (isEmailVariation(variation)) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                     mode = KeyboardId.MODE_EMAIL;
                 } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                     mode = KeyboardId.MODE_URL;
                 } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
                     mode = KeyboardId.MODE_IM;
                 } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                     mode = KeyboardId.MODE_TEXT;
                 } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
                     mode = KeyboardId.MODE_WEB;
@@ -570,7 +569,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
                 // If NO_SUGGESTIONS is set, don't do prediction.
                 if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                     mInputTypeNoAutoCorrect = true;
                 }
                 // If it's not multiline and the autoCorrect flag is not set, then don't correct
@@ -579,7 +578,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     mInputTypeNoAutoCorrect = true;
                 }
                 if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
-                    mPredictionOn = false;
+                    mIsSettingsSuggestionStripOn = false;
                     mApplicationSpecifiedCompletionOn = isFullscreenMode();
                 }
                 break;
@@ -589,7 +588,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
         inputView.closing();
         mComposing.setLength(0);
-        mPredicting = false;
+        mHasValidSuggestions = false;
         mDeleteCount = 0;
         mJustAddedAutoSpace = false;
 
@@ -613,7 +612,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
         inputView.setPreviewEnabled(mPopupOn);
         inputView.setProximityCorrectionEnabled(true);
-        mPredictionOn = mPredictionOn && (mCorrectionMode > 0 || isSuggestionShown());
+        mIsSettingsSuggestionStripOn &= (mCorrectionMode > 0 || isShowingSuggestionsStrip());
         // If we just entered a text field, maybe it has some old text that requires correction
         checkReCorrectionOnStart();
         inputView.setForeground(true);
@@ -631,7 +630,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // There could be a pending composing span.  Clean it up first.
         ic.finishComposingText();
 
-        if (isSuggestionShown() && isPredictionOn()) {
+        if (isShowingSuggestionsStrip() && 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
@@ -702,11 +701,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
         // If the current selection in the text view changes, we should
         // clear whatever candidate text we have.
-        if ((((mComposing.length() > 0 && mPredicting)
+        if ((((mComposing.length() > 0 && mHasValidSuggestions)
                 || mVoiceConnector.isVoiceInputHighlighted()) && (newSelStart != candidatesEnd
                         || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) {
             mComposing.setLength(0);
-            mPredicting = false;
+            mHasValidSuggestions = false;
             mHandler.postUpdateSuggestions();
             TextEntryState.reset();
             InputConnection ic = getCurrentInputConnection();
@@ -714,7 +713,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                 ic.finishComposingText();
             }
             mVoiceConnector.setVoiceInputHighlighted(false);
-        } else if (!mPredicting && !mJustAccepted) {
+        } else if (!mHasValidSuggestions && !mJustAccepted) {
             switch (TextEntryState.getState()) {
             case ACCEPTED_DEFAULT:
                 TextEntryState.reset();
@@ -733,14 +732,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         mLastSelectionStart = newSelStart;
         mLastSelectionEnd = newSelEnd;
 
-        if (mReCorrectionEnabled && isSuggestionShown()) {
+        if (mReCorrectionEnabled && isShowingSuggestionsStrip()) {
             // Don't look for corrections if the keyboard is not visible
             if (mKeyboardSwitcher.isInputViewShown()) {
                 // Check if we should go in or out of correction mode.
-                if (isPredictionOn() && !mJustReverted
+                if (isSuggestionsRequested() && !mJustReverted
                         && (candidatesStart == candidatesEnd || newSelStart != oldSelStart
                                 || TextEntryState.isCorrecting())
-                                && (newSelStart < newSelEnd - 1 || (!mPredicting))) {
+                                && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) {
                     if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) {
                         mHandler.postUpdateOldSuggestions();
                     } else {
@@ -767,7 +766,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
      */
     @Override
     public void onExtractedTextClicked() {
-        if (mReCorrectionEnabled && isPredictionOn()) return;
+        if (mReCorrectionEnabled && isSuggestionsRequested()) return;
 
         super.onExtractedTextClicked();
     }
@@ -783,7 +782,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
      */
     @Override
     public void onExtractedCursorMovement(int dx, int dy) {
-        if (mReCorrectionEnabled && isPredictionOn()) return;
+        if (mReCorrectionEnabled && isSuggestionsRequested()) return;
 
         super.onExtractedCursorMovement(dx, dy);
     }
@@ -905,8 +904,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     }
 
     public void commitTyped(InputConnection inputConnection) {
-        if (mPredicting) {
-            mPredicting = false;
+        if (mHasValidSuggestions) {
+            mHasValidSuggestions = false;
             if (mComposing.length() > 0) {
                 if (inputConnection != null) {
                     inputConnection.commitText(mComposing, 1);
@@ -1149,14 +1148,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
         mVoiceConnector.handleBackspace();
 
-        if (mPredicting) {
+        if (mHasValidSuggestions) {
             final int length = mComposing.length();
             if (length > 0) {
                 mComposing.delete(length - 1, length);
                 mWord.deleteLast();
                 ic.setComposingText(mComposing, 1);
                 if (mComposing.length() == 0) {
-                    mPredicting = false;
+                    mHasValidSuggestions = false;
                 }
                 mHandler.postUpdateSuggestions();
             } else {
@@ -1235,9 +1234,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
 
         int code = primaryCode;
-        if (isAlphabet(code) && isPredictionOn() && !isCursorTouchingWord()) {
-            if (!mPredicting) {
-                mPredicting = true;
+        if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) {
+            if (!mHasValidSuggestions) {
+                mHasValidSuggestions = true;
                 mComposing.setLength(0);
                 saveWordInHistory(mBestWord);
                 mWord.reset();
@@ -1262,7 +1261,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                 }
             }
         }
-        if (mPredicting) {
+        if (mHasValidSuggestions) {
             if (mComposing.length() == 0 && switcher.isAlphabetMode()
                     && switcher.isShiftedOrShiftLocked()) {
                 mWord.setFirstCharCapitalized(true);
@@ -1301,7 +1300,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             ic.beginBatchEdit();
             abortCorrection(false);
         }
-        if (mPredicting) {
+        if (mHasValidSuggestions) {
             // In certain languages where single quote is a separator, it's better
             // not to auto correct, but accept the typed word. For instance,
             // in Italian dov' should not be expanded to dove' because the elision
@@ -1334,7 +1333,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
                 && primaryCode != Keyboard.CODE_ENTER) {
             swapPunctuationAndSpace();
-        } else if (isPredictionOn() && primaryCode == Keyboard.CODE_SPACE) {
+        } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
             doubleSpace();
         }
         if (pickedDefault) {
@@ -1384,26 +1383,28 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         mWordHistory.add(entry);
     }
 
-    private boolean isPredictionOn() {
-        return mPredictionOn;
+    private boolean isSuggestionsRequested() {
+        return mIsSettingsSuggestionStripOn;
     }
 
     private boolean isShowingPunctuationList() {
         return mSuggestPuncList == mCandidateView.getSuggestions();
     }
 
-    private boolean isSuggestionShown() {
+    private boolean isShowingSuggestionsStrip() {
         return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE)
                 || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE
                         && mOrientation == Configuration.ORIENTATION_PORTRAIT);
     }
 
     private boolean isCandidateStripVisible() {
-        boolean forceVisible = mCandidateView.isShowingAddToDictionaryHint()
-                || TextEntryState.isCorrecting();
-        return forceVisible || (
-                isSuggestionShown() && (isPredictionOn() || mApplicationSpecifiedCompletionOn
-                        || isShowingPunctuationList()));
+        if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isCorrecting())
+            return true;
+        if (!isShowingSuggestionsStrip())
+            return false;
+        if (mApplicationSpecifiedCompletionOn)
+            return true;
+        return isSuggestionsRequested();
     }
 
     public void switchToKeyboardView() {
@@ -1451,12 +1452,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         mKeyboardSwitcher.setPreferredLetters(null);
 
         // Check if we have a suggestion engine attached.
-        if ((mSuggest == null || !isPredictionOn())
+        if ((mSuggest == null || !isSuggestionsRequested())
                 && !mVoiceConnector.isVoiceInputHighlighted()) {
             return;
         }
 
-        if (!mPredicting) {
+        if (!mHasValidSuggestions) {
             setPunctuationSuggestions();
             return;
         }
@@ -1500,7 +1501,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         correctionAvailable &= !word.isMostlyCaps();
         correctionAvailable &= !TextEntryState.isCorrecting();
 
-        builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable);
+        if (builder.size() > 1 || mCandidateView.isShowingAddToDictionaryHint()) {
+            builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable);
+        } else {
+            final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
+            if (previousSuggestions == mSuggestPuncList)
+                return;
+            builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+        }
         showSuggestions(builder.build(), typedWord);
     }
 
@@ -1634,7 +1642,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             ic.commitText(suggestion, 1);
         }
         saveWordInHistory(suggestion);
-        mPredicting = false;
+        mHasValidSuggestions = false;
         mCommittedLength = suggestion.length();
         switcher.setPreferredLetters(null);
     }
@@ -1693,7 +1701,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
         InputConnection ic = getCurrentInputConnection();
         if (ic == null) return;
-        if (!mPredicting) {
+        if (!mHasValidSuggestions) {
             // Extract the selected or touching text
             EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic,
                     mLastSelectionStart, mLastSelectionEnd, mWordSeparators);
@@ -1720,8 +1728,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     }
 
     private void setPunctuationSuggestions() {
-        setCandidatesViewShown(isCandidateStripVisible());
         setSuggestions(mSuggestPuncList);
+        setCandidatesViewShown(isCandidateStripVisible());
     }
 
     private void addToDictionaries(CharSequence suggestion, int frequencyDelta) {
@@ -1786,9 +1794,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     public void revertLastWord(boolean deleteChar) {
         final int length = mComposing.length();
-        if (!mPredicting && length > 0) {
+        if (!mHasValidSuggestions && length > 0) {
             final InputConnection ic = getCurrentInputConnection();
-            mPredicting = true;
+            mHasValidSuggestions = true;
             mJustReverted = true;
             if (deleteChar) ic.deleteSurroundingText(1, 0);
             int toDelete = mCommittedLength;
@@ -2153,9 +2161,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         p.println("LatinIME state :");
         p.println("  Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
         p.println("  mComposing=" + mComposing.toString());
-        p.println("  mPredictionOn=" + mPredictionOn);
+        p.println("  mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn);
         p.println("  mCorrectionMode=" + mCorrectionMode);
-        p.println("  mPredicting=" + mPredicting);
+        p.println("  mHasValidSuggestions=" + mHasValidSuggestions);
         p.println("  mAutoCorrectOn=" + mAutoCorrectOn);
         p.println("  mAutoSpace=" + mAutoSpace);
         p.println("  mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index a30ec1587767e7cd1a4029164e6b2490c7c154bc..2365902844b756e7e3fbd705cc7ce873c90cb6b2 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -345,7 +345,7 @@ public class Suggest implements Dictionary.WordCallback {
             }
         }
         removeDupes();
-        return new SuggestedWords.Builder().setWords(mSuggestions);
+        return new SuggestedWords.Builder().addWords(mSuggestions);
     }
 
     public int[] getNextLettersFrequencies() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 0bb7c66d1365caa3fdf5d25ba68b9e83da58ea12..5398b77b2769955c2b7d66c774bf93cce2770501 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -63,7 +63,7 @@ public class SuggestedWords {
     public static class Builder {
         private List<CharSequence> mWords;
         private boolean mIsCompletions;
-        private boolean mTypedWordVallid;
+        private boolean mTypedWordValid;
         private boolean mHasMinimalSuggestion;
         private Object[] mDebugInfo;
 
@@ -71,8 +71,9 @@ public class SuggestedWords {
             // Nothing to do here.
         }
 
-        public Builder setWords(List<CharSequence> words) {
-            mWords = words;
+        public Builder addWords(List<CharSequence> words) {
+            for (final CharSequence word : words)
+                addWord(word);
             return this;
         }
 
@@ -103,7 +104,7 @@ public class SuggestedWords {
         }
 
         public Builder setTypedWordValid(boolean typedWordValid) {
-            mTypedWordVallid = typedWordValid;
+            mTypedWordValid = typedWordValid;
             return this;
         }
 
@@ -112,13 +113,32 @@ public class SuggestedWords {
             return this;
         }
 
-        public CharSequence getWord(int pos) {
-            return mWords.get(pos);
+        // Should get rid of the first one (what the user typed previously) from suggestions
+        // and replace it with what the user currently typed.
+        public Builder addTypedWordAndPreviousSuggestions(CharSequence typedWord,
+                SuggestedWords previousSuggestions) {
+            if (mWords != null) mWords.clear();
+            addWord(typedWord);
+            final int previousSize = previousSuggestions.size();
+            for (int pos = 1; pos < previousSize; pos++)
+                addWord(previousSuggestions.getWord(pos));
+            mIsCompletions = false;
+            mTypedWordValid = false;
+            mHasMinimalSuggestion = (previousSize > 1);
+            return this;
         }
 
         public SuggestedWords build() {
-            return new SuggestedWords(mWords, mIsCompletions, mTypedWordVallid,
+            return new SuggestedWords(mWords, mIsCompletions, mTypedWordValid,
                     mHasMinimalSuggestion, mDebugInfo);
         }
+
+        public int size() {
+            return mWords == null ? 0 : mWords.size();
+        }
+
+        public CharSequence getWord(int pos) {
+            return mWords.get(pos);
+        }
     }
 }
diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
index c532a0baf0d3caba33a0dddb3b501a4c99cba574..d9528eb4098640d57a40ebe5256230e7e5c2bd9e 100644
--- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
+++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
@@ -435,7 +435,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
                     builder.addWord(word);
                 }
             } else {
-                builder.setWords(suggestions);
+                builder.addWords(suggestions);
             }
             builder.setTypedWordValid(true).setHasMinimalSuggestion(true);
             mContext.setSuggestions(builder.build());