diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 612ed424da7187afd0a03271a42eb8539c567d33..accc6307af2ae5b7e7247c81e510dd649ac0ad64 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import android.text.TextUtils;
+
 import java.util.ArrayList;
 
 /**
@@ -45,6 +47,9 @@ public class LastComposedWord {
     public final String mTypedWord;
     public final String mAutoCorrection;
 
+    public static final LastComposedWord NOT_A_COMPOSED_WORD =
+            new LastComposedWord(COMMIT_TYPE_USER_TYPED_WORD, null, null, null, "", "");
+
     public LastComposedWord(final int type, final ArrayList<int[]> codes, final int[] xCoordinates,
             final int[] yCoordinates, final String typedWord, final String autoCorrection) {
         mType = type;
@@ -54,4 +59,9 @@ public class LastComposedWord {
         mTypedWord = typedWord;
         mAutoCorrection = autoCorrection;
     }
+
+    public boolean didAutoCorrectToAnotherWord() {
+        return !TextUtils.isEmpty(mAutoCorrection)
+                && !TextUtils.equals(mTypedWord, mAutoCorrection);
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 51e3998c4386c88adcc36e2b14e4c464d4ac730c..5ef35dab51c7798a25d223a85a2e6f9c84e5264a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -199,6 +199,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
     private UserUnigramDictionary mUserUnigramDictionary;
     private boolean mIsUserDictionaryAvailable;
 
+    private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
     private WordComposer mWordComposer = new WordComposer();
 
     private int mCorrectionMode;
@@ -769,7 +770,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
 
         inputView.closing();
         mEnteredText = null;
-        mWordComposer.reset();
+        resetComposingState(true /* alsoResetLastComposedWord */);
         mDeleteCount = 0;
         mSpaceState = SPACE_STATE_NONE;
 
@@ -881,7 +882,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             if (((mWordComposer.isComposingWord())
                     || mVoiceProxy.isVoiceInputHighlighted())
                     && (selectionChanged || candidatesCleared)) {
-                mWordComposer.reset();
+                resetComposingState(true /* alsoResetLastComposedWord */);
                 updateSuggestions();
                 final InputConnection ic = getCurrentInputConnection();
                 if (ic != null) {
@@ -890,7 +891,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
                 mComposingStateManager.onFinishComposingText();
                 mVoiceProxy.setVoiceInputHighlighted(false);
             } else if (!mWordComposer.isComposingWord()) {
-                mWordComposer.reset();
+                // TODO: is the following reset still needed, given that we are not composing
+                // a word?
+                resetComposingState(true /* alsoResetLastComposedWord */);
                 updateSuggestions();
             }
         }
@@ -975,6 +978,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             // When in fullscreen mode, show completions generated by the application
             setSuggestions(builder.build());
             mWordComposer.deleteAutoCorrection();
+            mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
             setSuggestionStripShown(true);
         }
     }
@@ -1093,10 +1097,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         return super.onKeyUp(keyCode, event);
     }
 
+    private void resetComposingState(final boolean alsoResetLastComposedWord) {
+        mWordComposer.reset();
+        if (alsoResetLastComposedWord)
+            mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
+    }
+
     public void commitTyped(final InputConnection ic) {
         if (!mWordComposer.isComposingWord()) return;
         final CharSequence typedWord = mWordComposer.getTypedWord();
-        mWordComposer.onCommitWord(LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD);
+        mLastComposedWord = mWordComposer.commitWord(LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD);
         if (typedWord.length() > 0) {
             if (ic != null) {
                 ic.commitText(typedWord, 1);
@@ -1325,7 +1335,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
         mSpaceState = SPACE_STATE_NONE;
         mEnteredText = text;
-        mWordComposer.reset();
+        resetComposingState(true /* alsoResetLastComposedWord */);
     }
 
     @Override
@@ -1383,7 +1393,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             // resuming here. The behavior needs to be different according to text field types,
             // and it would be much clearer to test for them explicitly here rather than
             // relying on implicit values like "whether the suggestion strip is displayed".
-            if (mWordComposer.didAutoCorrectToAnotherWord()) {
+            if (mLastComposedWord.didAutoCorrectToAnotherWord()) {
                 Utils.Stats.onAutoCorrectionCancellation();
                 cancelAutoCorrect(ic);
                 return;
@@ -1495,7 +1505,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
                 // separator and it should be treated as a normal character, except in the first
                 // position where it should not start composing a word.
                 isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != code);
-                mWordComposer.reset();
+                // Here we don't need to reset the last composed word. It will be reset
+                // when we commit this one, if we ever do; if on the other hand we backspace
+                // it entirely and resume suggestions on the previous word, we'd like to still
+                // have touch coordinates for it.
+                resetComposingState(false /* alsoResetLastComposedWord */);
                 clearSuggestions();
                 mComposingStateManager.onFinishComposingText();
             }
@@ -1987,7 +2001,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         // what user typed. Note: currently this is done much later in
         // WordComposer#didAutoCorrectToAnotherWord by string equality of the remembered
         // strings.
-        mWordComposer.onCommitWord(commitType);
+        mLastComposedWord = mWordComposer.commitWord(commitType);
     }
 
     private static final WordComposer sEmptyWordComposer = new WordComposer();
@@ -2176,7 +2190,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         // Re-insert the separator
         ic.commitText(separator, 1);
         mWordComposer.deleteAutoCorrection();
-        mWordComposer.onCommitWord(LastComposedWord.COMMIT_TYPE_CANCEL_AUTO_CORRECT);
+        mLastComposedWord =
+                mWordComposer.commitWord(LastComposedWord.COMMIT_TYPE_CANCEL_AUTO_CORRECT);
         Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
                 WordComposer.NOT_A_COORDINATE);
         mHandler.cancelUpdateBigramPredictions();
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index adadd9394d58831ecc12120ca5f25b23c12b27a1..f97eb52f616eadc4301dcff5a85d18a40d9b8b47 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -330,7 +330,7 @@ public class WordComposer {
     }
 
     // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
-    public LastComposedWord onCommitWord(final int type) {
+    public LastComposedWord commitWord(final int type) {
         mCommittedWordSavedForSuggestionResuming = mCurrentWord;
         // Note: currently, we come here whenever we commit a word. If it's any *other* kind than
         // DECIDED_WORD, we should reset mAutoCorrection so that we don't attempt to cancel later.
@@ -348,7 +348,9 @@ public class WordComposer {
         }
         final LastComposedWord lastComposedWord = new LastComposedWord(type, mCurrentWord.mCodes,
                 mCurrentWord.mXCoordinates, mCurrentWord.mYCoordinates,
-                mCurrentWord.mTypedWord.toString(), mCurrentWord.mAutoCorrection.toString());
+                mCurrentWord.mTypedWord.toString(),
+                null == mCurrentWord.mAutoCorrection
+                        ? null : mCurrentWord.mAutoCorrection.toString());
         // TODO: improve performance by swapping buffers instead of creating a new object.
         mCurrentWord = new CharacterStore();
         return lastComposedWord;
@@ -362,11 +364,4 @@ public class WordComposer {
         mCurrentWord = mCommittedWordSavedForSuggestionResuming;
         mCommittedWordSavedForSuggestionResuming = null;
     }
-
-    public boolean didAutoCorrectToAnotherWord() {
-        return null != mCommittedWordSavedForSuggestionResuming
-                && !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection)
-                && !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord,
-                        mCommittedWordSavedForSuggestionResuming.mAutoCorrection);
-    }
 }