diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java
index f02f7885a4a52632ca5d422171b7ea36c62a64f6..ef5b04747980205b207c0265b6f5cfaf36e07b18 100644
--- a/java/src/com/android/inputmethod/event/Event.java
+++ b/java/src/com/android/inputmethod/event/Event.java
@@ -257,6 +257,8 @@ public class Event {
 
     public boolean isConsumed() { return 0 != (FLAG_CONSUMED & mFlags); }
 
+    public boolean isGesture() { return EVENT_TYPE_GESTURE == mEventType; }
+
     // Returns whether this is a fake key press from the suggestion strip. This happens with
     // punctuation signs selected from the suggestion strip.
     public boolean isSuggestionStripPress() {
diff --git a/java/src/com/android/inputmethod/event/InputTransaction.java b/java/src/com/android/inputmethod/event/InputTransaction.java
index b18bf5638d55072a827c4ac255b79ca6c62cdf02..5bc9111de711be9639afa08f059aa0843f4840b8 100644
--- a/java/src/com/android/inputmethod/event/InputTransaction.java
+++ b/java/src/com/android/inputmethod/event/InputTransaction.java
@@ -33,7 +33,7 @@ public class InputTransaction {
 
     // Initial conditions
     public final SettingsValues mSettingsValues;
-    private final Event mEvent;
+    public final Event mEvent;
     public final long mTimestamp;
     public final int mSpaceState;
     public final int mShiftState;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2cf7a04c1b856d1b533cc5d8f7982ec8a4e9bf1f..71fd10e837a6cfd82999e662e491449297844298 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -138,7 +138,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     new Runnable() {
                         @Override
                         public void run() {
-                            mHandler.postUpdateSuggestionStrip();
+                            mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
                         }
                     });
     private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
@@ -220,7 +220,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             case MSG_UPDATE_SUGGESTION_STRIP:
                 cancelUpdateSuggestionStrip();
                 latinIme.mInputLogic.performUpdateSuggestionStripSync(
-                        latinIme.mSettings.getCurrent());
+                        latinIme.mSettings.getCurrent(), msg.arg1 /* inputStyle */);
                 break;
             case MSG_UPDATE_SHIFT_STATE:
                 switcher.requestUpdatingShiftState(latinIme.getCurrentAutoCapsState(),
@@ -270,8 +270,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             }
         }
 
-        public void postUpdateSuggestionStrip() {
-            sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP), mDelayUpdateSuggestions);
+        public void postUpdateSuggestionStrip(final int inputStyle) {
+            sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP, inputStyle,
+                    0 /* ignored */), mDelayUpdateSuggestions);
         }
 
         public void postReopenDictionaries() {
@@ -1060,7 +1061,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                         applicationSpecifiedCompletions);
         final SuggestedWords suggestedWords = new SuggestedWords(applicationSuggestedWords,
                 null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */,
-                false /* isObsoleteSuggestions */, false /* isPrediction */);
+                false /* isObsoleteSuggestions */, false /* isPrediction */,
+                SuggestedWords.INPUT_STYLE_APPLICATION_SPECIFIED /* inputStyle */);
         // When in fullscreen mode, show completions generated by the application forcibly
         setSuggestedWords(suggestedWords);
     }
@@ -1451,7 +1453,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     }
 
     // TODO[IL]: Move this out of LatinIME.
-    public void getSuggestedWords(final int sessionId, final int sequenceNumber,
+    public void getSuggestedWords(final int inputStyle, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
         final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
         if (keyboard == null) {
@@ -1459,7 +1461,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             return;
         }
         mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard.getProximityInfo(),
-                mKeyboardSwitcher.getKeyboardShiftMode(), sessionId, sequenceNumber, callback);
+                mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback);
     }
 
     @Override
@@ -1543,7 +1545,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         default: // SHIFT_NO_UPDATE
         }
         if (inputTransaction.requiresUpdateSuggestions()) {
-            mHandler.postUpdateSuggestionStrip();
+            final int inputStyle;
+            if (inputTransaction.mEvent.isSuggestionStripPress()) {
+                // Suggestion strip press: no input.
+                inputStyle = SuggestedWords.INPUT_STYLE_NONE;
+            } else if (inputTransaction.mEvent.isGesture()) {
+                inputStyle = SuggestedWords.INPUT_STYLE_TAIL_BATCH;
+            } else {
+                inputStyle = SuggestedWords.INPUT_STYLE_TYPING;
+            }
+            mHandler.postUpdateSuggestionStrip(inputStyle);
         }
         if (inputTransaction.didAffectContents()) {
             mSubtypeState.setCurrentSubtypeHasBeenUsed();
diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
index 0fba37c8ae397b560d04c2e6c2ff498637419b93..6b0205c0fa9a9ae745670699e8a13d6673c468d5 100644
--- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
@@ -35,7 +35,8 @@ public final class PunctuationSuggestions extends SuggestedWords {
                 false /* typedWordValid */,
                 false /* hasAutoCorrectionCandidate */,
                 false /* isObsoleteSuggestions */,
-                false /* isPrediction */);
+                false /* isPrediction */,
+                INPUT_STYLE_NONE /* inputStyle */);
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index b8b6d647180b3f0e4bf6119ee112582954455a11..ab852f8ddbef0d622275790602efdae86ef1ba7b 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -40,13 +40,8 @@ public final class Suggest {
     // Session id for
     // {@link #getSuggestedWords(WordComposer,String,ProximityInfo,boolean,int)}.
     // We are sharing the same ID between typing and gesture to save RAM footprint.
-    public static final int SESSION_TYPING = 0;
-    public static final int SESSION_GESTURE = 0;
-
-    // TODO: rename this to CORRECTION_OFF
-    public static final int CORRECTION_NONE = 0;
-    // TODO: rename this to CORRECTION_ON
-    public static final int CORRECTION_FULL = 1;
+    public static final int SESSION_ID_TYPING = 0;
+    public static final int SESSION_ID_GESTURE = 0;
 
     // Close to -2**31
     private static final int SUPPRESS_SUGGEST_THRESHOLD = -2000000000;
@@ -75,14 +70,15 @@ public final class Suggest {
     public void getSuggestedWords(final WordComposer wordComposer,
             final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
             final SettingsValuesForSuggestion settingsValuesForSuggestion,
-            final boolean isCorrectionEnabled, final int sessionId, final int sequenceNumber,
+            final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
         if (wordComposer.isBatchMode()) {
             getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo,
-                    settingsValuesForSuggestion, sessionId, sequenceNumber, callback);
+                    settingsValuesForSuggestion, inputStyle, sequenceNumber, callback);
         } else {
-            getSuggestedWordsForTypingInput(wordComposer, prevWordsInfo, proximityInfo,
-                    settingsValuesForSuggestion, isCorrectionEnabled, sequenceNumber, callback);
+            getSuggestedWordsForNonBatchInput(wordComposer, prevWordsInfo, proximityInfo,
+                    settingsValuesForSuggestion, inputStyle, isCorrectionEnabled,
+                    sequenceNumber, callback);
         }
     }
 
@@ -120,11 +116,11 @@ public final class Suggest {
         return firstSuggestedWordInfo.mWord;
     }
 
-    // Retrieves suggestions for the typing input
+    // Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
     // and calls the callback function with the suggestions.
-    private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
+    private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
             final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
-            final SettingsValuesForSuggestion settingsValuesForSuggestion,
+            final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyle,
             final boolean isCorrectionEnabled, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
         final String typedWord = wordComposer.getTypedWord();
@@ -135,7 +131,7 @@ public final class Suggest {
 
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
                 wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
-                SESSION_TYPING);
+                SESSION_ID_TYPING);
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
                         trailingSingleQuotesCount);
@@ -197,7 +193,8 @@ public final class Suggest {
                 // rename the attribute or change the value.
                 !resultsArePredictions && !allowsToBeAutoCorrected /* typedWordValid */,
                 hasAutoCorrection /* willAutoCorrect */,
-                false /* isObsoleteSuggestions */, resultsArePredictions, sequenceNumber));
+                false /* isObsoleteSuggestions */, resultsArePredictions,
+                inputStyle, sequenceNumber));
     }
 
     // Retrieves suggestions for the batch input
@@ -205,10 +202,11 @@ public final class Suggest {
     private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
             final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
             final SettingsValuesForSuggestion settingsValuesForSuggestion,
-            final int sessionId, final int sequenceNumber,
+            final int inputStyle, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
-                wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId);
+                wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
+                SESSION_ID_GESTURE);
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 new ArrayList<>(suggestionResults);
         final int suggestionsCount = suggestionsContainer.size();
@@ -246,7 +244,8 @@ public final class Suggest {
                 true /* typedWordValid */,
                 false /* willAutoCorrect */,
                 false /* isObsoleteSuggestions */,
-                false /* isPrediction */, sequenceNumber));
+                false /* isPrediction */,
+                inputStyle, sequenceNumber));
     }
 
     private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 5231cc8939d703373d32d49619917581acd76fd6..d7693af41bd45fcc906bf02a4965ce8509ee81b5 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -31,12 +31,20 @@ public class SuggestedWords {
     public static final int INDEX_OF_AUTO_CORRECTION = 1;
     public static final int NOT_A_SEQUENCE_NUMBER = -1;
 
+    public static final int INPUT_STYLE_NONE = 0;
+    public static final int INPUT_STYLE_TYPING = 1;
+    public static final int INPUT_STYLE_UPDATE_BATCH = 2;
+    public static final int INPUT_STYLE_TAIL_BATCH = 3;
+    public static final int INPUT_STYLE_APPLICATION_SPECIFIED = 4;
+    public static final int INPUT_STYLE_RECORRECTION = 5;
+
     // The maximum number of suggestions available.
     public static final int MAX_SUGGESTIONS = 18;
 
     private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = new ArrayList<>(0);
     public static final SuggestedWords EMPTY = new SuggestedWords(
-            EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false);
+            EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false,
+            INPUT_STYLE_NONE);
 
     public final String mTypedWord;
     public final boolean mTypedWordValid;
@@ -46,6 +54,9 @@ public class SuggestedWords {
     public final boolean mWillAutoCorrect;
     public final boolean mIsObsoleteSuggestions;
     public final boolean mIsPrediction;
+    // How the input for these suggested words was done by the user. Must be one of the
+    // INPUT_STYLE_* constants above.
+    public final int mInputStyle;
     public final int mSequenceNumber; // Sequence number for auto-commit.
     protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
     public final ArrayList<SuggestedWordInfo> mRawSuggestions;
@@ -55,9 +66,10 @@ public class SuggestedWords {
             final boolean typedWordValid,
             final boolean willAutoCorrect,
             final boolean isObsoleteSuggestions,
-            final boolean isPrediction) {
+            final boolean isPrediction,
+            final int inputStyle) {
         this(suggestedWordInfoList, rawSuggestions, typedWordValid, willAutoCorrect,
-                isObsoleteSuggestions, isPrediction, NOT_A_SEQUENCE_NUMBER);
+                isObsoleteSuggestions, isPrediction, inputStyle, NOT_A_SEQUENCE_NUMBER);
     }
 
     public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
@@ -66,11 +78,12 @@ public class SuggestedWords {
             final boolean willAutoCorrect,
             final boolean isObsoleteSuggestions,
             final boolean isPrediction,
+            final int inputStyle,
             final int sequenceNumber) {
         this(suggestedWordInfoList, rawSuggestions,
                 (suggestedWordInfoList.isEmpty() || isPrediction) ? null
                         : suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
-                typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction,
+                typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction, inputStyle,
                 sequenceNumber);
     }
 
@@ -81,6 +94,7 @@ public class SuggestedWords {
             final boolean willAutoCorrect,
             final boolean isObsoleteSuggestions,
             final boolean isPrediction,
+            final int inputStyle,
             final int sequenceNumber) {
         mSuggestedWordInfoList = suggestedWordInfoList;
         mRawSuggestions = rawSuggestions;
@@ -88,6 +102,7 @@ public class SuggestedWords {
         mWillAutoCorrect = willAutoCorrect;
         mIsObsoleteSuggestions = isObsoleteSuggestions;
         mIsPrediction = isPrediction;
+        mInputStyle = inputStyle;
         mSequenceNumber = sequenceNumber;
         mTypedWord = typedWord;
     }
@@ -367,7 +382,7 @@ public class SuggestedWords {
 
     // SuggestedWords is an immutable object, as much as possible. We must not just remove
     // words from the member ArrayList as some other parties may expect the object to never change.
-    public SuggestedWords getSuggestedWordsExcludingTypedWord() {
+    public SuggestedWords getSuggestedWordsExcludingTypedWord(final int inputStyle) {
         final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
         String typedWord = null;
         for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
@@ -383,7 +398,7 @@ public class SuggestedWords {
         // no auto-correction should take place hence willAutoCorrect = false.
         return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord,
                 true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions,
-                mIsPrediction, NOT_A_SEQUENCE_NUMBER);
+                mIsPrediction, inputStyle, NOT_A_SEQUENCE_NUMBER);
     }
 
     // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
@@ -402,6 +417,7 @@ public class SuggestedWords {
                     SuggestedWordInfo.NOT_A_CONFIDENCE));
         }
         return new SuggestedWords(newSuggestions, null /* rawSuggestions */, mTypedWordValid,
-                mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction);
+                mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction,
+                INPUT_STYLE_TAIL_BATCH);
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 418866ae11cca84eebf1675bc9acb8348e523d16..348bae63ae454fa8da9a4e352980d2994f538601 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -216,7 +216,7 @@ public final class InputLogic {
         } else {
             resetComposingState(true /* alsoResetLastComposedWord */);
         }
-        handler.postUpdateSuggestionStrip();
+        handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_TYPING);
         final String text = performSpecificTldProcessingOnTextInput(rawText);
         if (SpaceState.PHANTOM == mSpaceState) {
             promotePhantomSpace(settingsValues);
@@ -288,9 +288,6 @@ public final class InputLogic {
             return inputTransaction;
         }
 
-        // We need to log before we commit, because the word composer will store away the user
-        // typed word.
-        final String replacedWord = mWordComposer.getTypedWord();
         commitChosenWord(settingsValues, suggestion,
                 LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
         mConnection.endBatchEdit();
@@ -311,7 +308,8 @@ public final class InputLogic {
             mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
         } else {
             // If we're not showing the "Touch again to save", then update the suggestion strip.
-            handler.postUpdateSuggestionStrip();
+            // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
+            handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
         }
         return inputTransaction;
     }
@@ -1299,7 +1297,8 @@ public final class InputLogic {
                 prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive);
     }
 
-    public void performUpdateSuggestionStripSync(final SettingsValues settingsValues) {
+    public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
+            final int inputStyle) {
         // Check if we have a suggestion engine attached.
         if (!settingsValues.needsToLookupSuggestions()) {
             if (mWordComposer.isComposingWord()) {
@@ -1317,8 +1316,8 @@ public final class InputLogic {
         }
 
         final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<>();
-        mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
-                SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
+        mInputLogicHandler.getSuggestedWords(inputStyle, SuggestedWords.NOT_A_SEQUENCE_NUMBER,
+                new OnGetSuggestedWordsCallback() {
                     @Override
                     public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
                         final String typedWord = mWordComposer.getTypedWord();
@@ -1379,7 +1378,7 @@ public final class InputLogic {
         if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)) {
             // Show predictions.
             mWordComposer.setCapitalizedModeAtStartComposingTime(WordComposer.CAPS_MODE_OFF);
-            mLatinIME.mHandler.postUpdateSuggestionStrip();
+            mLatinIME.mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_RECORRECTION);
             return;
         }
         final TextRange range = mConnection.getWordRangeAtCursor(
@@ -1444,7 +1443,7 @@ public final class InputLogic {
             // If there weren't any suggestion spans on this word, suggestions#size() will be 1
             // if shouldIncludeResumedWordInSuggestions is true, 0 otherwise. In this case, we
             // have no useful suggestions, so we will try to compute some for it instead.
-            mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
+            mInputLogicHandler.getSuggestedWords(Suggest.SESSION_ID_TYPING,
                     SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
                         @Override
                         public void onGetSuggestedWords(
@@ -1457,7 +1456,8 @@ public final class InputLogic {
                                 // case. The #getSuggestedWordsExcludingTypedWord() method sets
                                 // willAutoCorrect to false.
                                 suggestedWords = suggestedWordsIncludingTypedWord
-                                        .getSuggestedWordsExcludingTypedWord();
+                                        .getSuggestedWordsExcludingTypedWord(SuggestedWords
+                                                .INPUT_STYLE_RECORRECTION);
                             } else {
                                 // No saved suggestions, and we were unable to compute any good one
                                 // either. Rather than displaying an empty suggestion strip, we'll
@@ -1477,6 +1477,7 @@ public final class InputLogic {
                     null /* rawSuggestions */, typedWord,
                     false /* typedWordValid */, false /* willAutoCorrect */,
                     false /* isObsoleteSuggestions */, false /* isPrediction */,
+                    SuggestedWords.INPUT_STYLE_RECORRECTION,
                     SuggestedWords.NOT_A_SEQUENCE_NUMBER);
             mIsAutoCorrectionIndicatorOn = false;
             mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
@@ -1773,7 +1774,8 @@ public final class InputLogic {
                 SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords);
         return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
                 false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
-                true /* isObsoleteSuggestions */, false /* isPrediction */);
+                true /* isObsoleteSuggestions */, false /* isPrediction */,
+                oldSuggestedWords.mInputStyle);
     }
 
     /**
@@ -1956,7 +1958,15 @@ public final class InputLogic {
         // Complete any pending suggestions query first
         if (handler.hasPendingUpdateSuggestions()) {
             handler.cancelUpdateSuggestionStrip();
-            performUpdateSuggestionStripSync(settingsValues);
+            // To know the input style here, we should retrieve the in-flight "update suggestions"
+            // message and read its arg1 member here. However, the Handler class does not let
+            // us retrieve this message, so we can't do that. But in fact, we notice that
+            // we only ever come here when the input style was typing. In the case of batch
+            // input, we update the suggestions synchronously when the tail batch comes. Likewise
+            // for application-specified completions. As for recorrections, we never auto-correct,
+            // so we don't come here either. Hence, the input style is necessarily
+            // INPUT_STYLE_TYPING.
+            performUpdateSuggestionStripSync(settingsValues, SuggestedWords.INPUT_STYLE_TYPING);
         }
         final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
         final String typedWord = mWordComposer.getTypedWord();
@@ -2052,7 +2062,7 @@ public final class InputLogic {
     }
 
     public void getSuggestedWords(final SettingsValues settingsValues,
-            final ProximityInfo proximityInfo, final int keyboardShiftMode, final int sessionId,
+            final ProximityInfo proximityInfo, final int keyboardShiftMode, final int inputStyle,
             final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
         mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions(
                 getActualCapsMode(settingsValues, keyboardShiftMode));
@@ -2068,6 +2078,6 @@ public final class InputLogic {
                         settingsValues.mPhraseGestureEnabled,
                         settingsValues.mAdditionalFeaturesSettingValues),
                 settingsValues.mAutoCorrectionEnabledPerUserSettings,
-                sessionId, sequenceNumber, callback);
+                inputStyle, sequenceNumber, callback);
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
index 9dbe2c38b4c24d8c60e571da95d42da30ee5f186..c6f83d0b922de22b4f2e66ba9fa526ec70a607ca 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
@@ -96,7 +96,7 @@ class InputLogicHandler implements Handler.Callback {
     public boolean handleMessage(final Message msg) {
         switch (msg.what) {
             case MSG_GET_SUGGESTED_WORDS:
-                mLatinIME.getSuggestedWords(msg.arg1 /* sessionId */,
+                mLatinIME.getSuggestedWords(msg.arg1 /* inputStyle */,
                         msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj);
                 break;
         }
@@ -134,7 +134,8 @@ class InputLogicHandler implements Handler.Callback {
                 return;
             }
             mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
-            getSuggestedWords(Suggest.SESSION_GESTURE, sequenceNumber,
+            getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH
+                    : SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber,
                     new OnGetSuggestedWordsCallback() {
                         @Override
                         public void onGetSuggestedWords(SuggestedWords suggestedWords) {
@@ -205,9 +206,9 @@ class InputLogicHandler implements Handler.Callback {
         updateBatchInput(batchPointers, sequenceNumber, true /* isTailBatchInput */);
     }
 
-    public void getSuggestedWords(final int sessionId, final int sequenceNumber,
+    public void getSuggestedWords(final int inputStyle, final int sequenceNumber,
             final OnGetSuggestedWordsCallback callback) {
         mNonUIThreadHandler.obtainMessage(
-                MSG_GET_SUGGESTED_WORDS, sessionId, sequenceNumber, callback).sendToTarget();
+                MSG_GET_SUGGESTED_WORDS, inputStyle, sequenceNumber, callback).sendToTarget();
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 66b4a9c71d111b5701fd9ebe414d7bda7a2cad7b..a5f20b5656d3525613217be123f159ce712dbded 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -48,7 +48,8 @@ public class SuggestedWordsTests extends AndroidTestCase {
                 false /* typedWordValid */,
                 false /* willAutoCorrect */,
                 false /* isObsoleteSuggestions */,
-                false /* isPrediction*/);
+                false /* isPrediction*/,
+                SuggestedWords.INPUT_STYLE_NONE);
         assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
         assertEquals("typed", words.getWord(0));
         assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED));
@@ -57,7 +58,8 @@ public class SuggestedWordsTests extends AndroidTestCase {
         assertEquals("4", words.getWord(5));
         assertTrue(words.getInfo(5).isKindOf(SuggestedWordInfo.KIND_CORRECTION));
 
-        final SuggestedWords wordsWithoutTyped = words.getSuggestedWordsExcludingTypedWord();
+        final SuggestedWords wordsWithoutTyped = words.getSuggestedWordsExcludingTypedWord(
+                SuggestedWords.INPUT_STYLE_NONE);
         assertEquals(words.size() - 1, wordsWithoutTyped.size());
         assertEquals("0", wordsWithoutTyped.getWord(0));
         assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(SuggestedWordInfo.KIND_CORRECTION));