diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 75a7391061fd4b0e4bbde67fe3db2b27acb8215e..6b939cdfe6ac9184b850ccbab213d8cdf6ba965e 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -21,6 +21,7 @@ import android.util.Pair;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.KeyboardLayout;
+import com.android.inputmethod.latin.common.ComposedData;
 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
 import com.android.inputmethod.latin.utils.SuggestionResults;
 
@@ -155,7 +156,7 @@ public interface DictionaryFacilitator {
             final int eventType);
 
     // TODO: Revise the way to fusion suggestion results.
-    SuggestionResults getSuggestionResults(final WordComposer composer,
+    SuggestionResults getSuggestionResults(final ComposedData composedData,
             final NgramContext ngramContext, final long proximityInfoHandle,
             final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
             final int inputStyle, final KeyboardLayout keyboardLayout);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index 2123567b7185c1ee7d0a65c1045e456f3588c697..e963000207a3ad41aea7c686363dc99ebfa2a7b0 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -25,6 +25,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.KeyboardLayout;
 import com.android.inputmethod.latin.NgramContext.WordInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.ComposedData;
 import com.android.inputmethod.latin.common.Constants;
 import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
@@ -666,7 +667,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
 
     // TODO: Revise the way to fusion suggestion results.
     @Override
-    public SuggestionResults getSuggestionResults(WordComposer composer,
+    public SuggestionResults getSuggestionResults(ComposedData composedData,
             NgramContext ngramContext, long proximityInfoHandle,
             SettingsValuesForSuggestion settingsValuesForSuggestion, int sessionId,
             int inputStyle, KeyboardLayout keyboardLayout) {
@@ -679,11 +680,11 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             for (final String dictType : DICTIONARY_TYPES_FOR_SUGGESTIONS) {
                 final Dictionary dictionary = dictionaryGroup.getDict(dictType);
                 if (null == dictionary) continue;
-                final float weightForLocale = composer.isBatchMode()
+                final float weightForLocale = composedData.mIsBatchMode
                         ? dictionaryGroup.mWeightForGesturingInLocale
                         : dictionaryGroup.mWeightForTypingInLocale;
                 final ArrayList<SuggestedWordInfo> dictionarySuggestions =
-                        dictionary.getSuggestions(composer.getComposedDataSnapshot(), ngramContext,
+                        dictionary.getSuggestions(composedData, ngramContext,
                                 proximityInfoHandle, settingsValuesForSuggestion, sessionId,
                                 weightForLocale, weightOfLangModelVsSpatialModel);
                 if (null == dictionarySuggestions) continue;
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index ddb2b5358ce5da4c859848a05cd74720e59ded5e..428956a7bc1a889493f6f3fec0d21f7a22a62a3d 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -176,9 +176,9 @@ public final class Suggest {
                 : typedWordString;
 
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
-                wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
-                settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction,
-                keyboardLayout);
+                wordComposer.getComposedDataSnapshot(), ngramContext,
+                proximityInfo.getNativeProximityInfo(), settingsValuesForSuggestion,
+                SESSION_ID_TYPING, inputStyleIfNotPrediction, keyboardLayout);
         final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
@@ -349,8 +349,9 @@ public final class Suggest {
             final OnGetSuggestedWordsCallback callback,
             final KeyboardLayout keyboardLayout) {
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
-                wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
-                settingsValuesForSuggestion, SESSION_ID_GESTURE, inputStyle, keyboardLayout);
+                wordComposer.getComposedDataSnapshot(), ngramContext,
+                proximityInfo.getNativeProximityInfo(), settingsValuesForSuggestion,
+                SESSION_ID_GESTURE, inputStyle, keyboardLayout);
         // For transforming words that don't come from a dictionary, because it's our best bet
         final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index d35d1f2f55e1adc4a5e0d6e7f8abd951415e14bb..9822c5725c55a96205065cccc82dcf63b2f5d911 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -37,11 +37,11 @@ import com.android.inputmethod.latin.NgramContext;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodSubtype;
 import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.common.ComposedData;
 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.ScriptUtils;
 import com.android.inputmethod.latin.utils.SuggestionResults;
-import com.android.inputmethod.latin.WordComposer;
 
 import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
@@ -191,16 +191,16 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
         }
     }
 
-    public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer,
-            final NgramContext ngramContext, final ProximityInfo proximityInfo,
-            final KeyboardLayout keyboardLayout) {
+    public SuggestionResults getSuggestionResults(final Locale locale,
+            final ComposedData composedData, final NgramContext ngramContext,
+            final ProximityInfo proximityInfo, final KeyboardLayout keyboardLayout) {
         Integer sessionId = null;
         mSemaphore.acquireUninterruptibly();
         try {
             sessionId = mSessionIdPool.poll();
             DictionaryFacilitator dictionaryFacilitatorForLocale =
                     mDictionaryFacilitatorCache.get(locale);
-            return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext,
+            return dictionaryFacilitatorForLocale.getSuggestionResults(composedData, ngramContext,
                     proximityInfo.getNativeProximityInfo(), mSettingsValuesForSuggestion,
                     sessionId, SuggestedWords.INPUT_STYLE_TYPING, keyboardLayout);
         } finally {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 0b5e12f03ffc91344522034c45cf7bba2033a8af..1c43a4b71aa5bfa20c9f26f7a604fa6e5f63fa6c 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -32,11 +32,15 @@ import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardLayout;
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.NgramContext;
+import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.common.ComposedData;
 import com.android.inputmethod.latin.common.Constants;
 import com.android.inputmethod.latin.common.CoordinateUtils;
+import com.android.inputmethod.latin.common.InputPointers;
 import com.android.inputmethod.latin.common.LocaleUtils;
+import com.android.inputmethod.latin.common.ResizableIntArray;
 import com.android.inputmethod.latin.common.StringUtils;
 import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
 import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -286,7 +290,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
             composer.setComposingWord(codePoints, coordinates);
             // TODO: Don't gather suggestions if the limit is <= 0 unless necessary
             final SuggestionResults suggestionResults = mService.getSuggestionResults(
-                    mLocale, composer, ngramContext, proximityInfo, keyboardLayout);
+                    mLocale, composer.getComposedDataSnapshot(), ngramContext, proximityInfo,
+                    keyboardLayout);
             final Result result = getResult(capitalizeType, mLocale, suggestionsLimit,
                     mService.getRecommendedThreshold(), text, suggestionResults);
             isInDict = isInDictForAnyCapitalization(text, capitalizeType);