diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index eb19ef9325e9e6fb8f559574941c081b0724a7e4..e8b06570f2036564f87a979056cd7c41aae49abd 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -21,7 +21,6 @@ import android.util.SparseArray;
 
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.settings.AdditionalFeaturesSettingUtils;
 import com.android.inputmethod.latin.settings.NativeSuggestOptions;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.JniUtils;
@@ -120,15 +119,16 @@ public final class BinaryDictionary extends Dictionary {
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
-                0 /* sessionId */);
+                additionalFeaturesOptions, 0 /* sessionId */);
     }
 
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords, final int sessionId) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+            final int sessionId) {
         if (!isValidDictionary()) return null;
 
         Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE);
@@ -148,8 +148,7 @@ public final class BinaryDictionary extends Dictionary {
         final InputPointers ips = composer.getInputPointers();
         final int inputSize = isGesture ? ips.getPointerSize() : composerSize;
         mNativeSuggestOptions.setIsGesture(isGesture);
-        mNativeSuggestOptions.setAdditionalFeaturesOptions(
-                AdditionalFeaturesSettingUtils.getAdditionalNativeSuggestOptions());
+        mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
         // proximityInfo and/or prevWordForBigrams may not be null.
         final int count = getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
                 getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index d9ded7ceb87c291ee236d96af6fcb5d45ebc4e23..8a3a884387504d189a9f5140a998ac3df6462486 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -72,20 +72,23 @@ public abstract class Dictionary {
      * @param prevWord the previous word, or null if none
      * @param proximityInfo the object for key proximity. May be ignored by some implementations.
      * @param blockOffensiveWords whether to block potentially offensive words
+     * @param additionalFeaturesOptions options about additional features used for the suggestion.
      * @return the list of suggestions (possibly null if none)
      */
     // TODO: pass more context than just the previous word, to enable better suggestions (n-gram
     // and more)
     abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords);
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions);
 
     // The default implementation of this method ignores sessionId.
     // Subclasses that want to use sessionId need to override this method.
     public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords, final int sessionId) {
-        return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords);
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+            final int sessionId) {
+        return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords,
+                additionalFeaturesOptions);
     }
 
     /**
@@ -156,7 +159,7 @@ public abstract class Dictionary {
         @Override
         public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
                 final String prevWord, final ProximityInfo proximityInfo,
-                final boolean blockOffensiveWords) {
+                final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
             return null;
         }
 
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index d05bb1e5501c4905918ba7d61bfb72a3734796f5..bf075140ebf3e9a48caef9f00fcf75f1521435cc 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -58,18 +58,18 @@ public final class DictionaryCollection extends Dictionary {
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries;
         if (dictionaries.isEmpty()) return null;
         // To avoid creating unnecessary objects, we get the list out of the first
         // dictionary and add the rest to it if not null, hence the get(0)
         ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
-                prevWord, proximityInfo, blockOffensiveWords);
+                prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions);
         if (null == suggestions) suggestions = CollectionUtils.newArrayList();
         final int length = dictionaries.size();
         for (int i = 1; i < length; ++ i) {
             final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
-                    prevWord, proximityInfo, blockOffensiveWords);
+                    prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions);
             if (null != sugg) suggestions.addAll(sugg);
         }
         return suggestions;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryWriter.java b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
index a97e053d0ad974a6450d237937a59d107047c4fc..5a453dde5452ef5d3ff01136550d73732ca6dfdc 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
@@ -92,7 +92,7 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            boolean blockOffensiveWords) {
+            boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         // This class doesn't support suggestion.
         return null;
     }
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 939c2a03be6b693b6ad9c2d1a8d255a3cdd652df..b92283c5b555f5670658cf8ad315499ac6e30399 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -272,19 +272,19 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         asyncReloadDictionaryIfRequired();
         // Write lock because getSuggestions in native updates session status.
         if (mLocalDictionaryController.writeLock().tryLock()) {
             try {
                 final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
                         mDictionaryWriter.getSuggestions(composer, prevWord, proximityInfo,
-                                blockOffensiveWords);
+                                blockOffensiveWords, additionalFeaturesOptions);
                 // TODO: Remove checking mIsUpdatable and use native suggestion.
                 if (mBinaryDictionary != null && !mIsUpdatable) {
                     final ArrayList<SuggestedWordInfo> binarySuggestion =
                             mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
-                                    blockOffensiveWords);
+                                    blockOffensiveWords, additionalFeaturesOptions);
                     if (inMemDictSuggestion == null) {
                         return binarySuggestion;
                     } else if (binarySuggestion == null) {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index f5fa5d0d7c58cda427bfc1b72527a006146a2055..342dcfc5e5ffd196babff43a487ae4ce9fa25c5a 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -210,7 +210,7 @@ public class ExpandableDictionary extends Dictionary {
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         if (composer.size() > 1) {
             if (composer.size() >= Constants.DICTIONARY_MAX_WORD_LENGTH) {
                 return null;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 85001c30cf510a8ced7f18fd876b894fa7a663ec..de4baf948934d9cc5460e9b85013b286d6c90845 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2323,6 +2323,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
         // should just skip whitespace if any, so 1.
         final SettingsValues currentSettings = mSettings.getCurrent();
+        final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues;
         final String prevWord;
         if (currentSettings.mCurrentLanguageHasSpaces) {
             // If we are typing in a language with spaces we can just look up the previous
@@ -2335,7 +2336,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
         return suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
                 currentSettings.mBlockPotentiallyOffensive,
-                currentSettings.mCorrectionEnabled, sessionId);
+                currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId);
     }
 
     private SuggestedWords getSuggestedWordsOrOlderSuggestions(final int sessionId) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index c8a151a6ca2b86588457d78d6641ebeadc3ba80f..826387a05f671afa7fba8ff8301ad24a69fa312e 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -214,21 +214,23 @@ public final class Suggest {
     public SuggestedWords getSuggestedWords(final WordComposer wordComposer,
             final String prevWordForBigram, final ProximityInfo proximityInfo,
             final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
-            final int sessionId) {
+            final int[] additionalFeaturesOptions, final int sessionId) {
         LatinImeLogger.onStartSuggestion(prevWordForBigram);
         if (wordComposer.isBatchMode()) {
             return getSuggestedWordsForBatchInput(
-                    wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId);
+                    wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords,
+                    additionalFeaturesOptions, sessionId);
         } else {
             return getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
-                    blockOffensiveWords, isCorrectionEnabled);
+                    blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions);
         }
     }
 
     // Retrieves suggestions for the typing input.
     private SuggestedWords getSuggestedWordsForTypingInput(final WordComposer wordComposer,
             final String prevWordForBigram, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords, final boolean isCorrectionEnabled) {
+            final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
+            final int[] additionalFeaturesOptions) {
         final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
         final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
                 MAX_SUGGESTIONS);
@@ -252,7 +254,8 @@ public final class Suggest {
         for (final String key : mDictionaries.keySet()) {
             final Dictionary dictionary = mDictionaries.get(key);
             suggestionsSet.addAll(dictionary.getSuggestions(
-                    wordComposerForLookup, prevWordForBigram, proximityInfo, blockOffensiveWords));
+                    wordComposerForLookup, prevWordForBigram, proximityInfo, blockOffensiveWords,
+                    additionalFeaturesOptions));
         }
 
         final String whitelistedWord;
@@ -343,7 +346,8 @@ public final class Suggest {
     // Retrieves suggestions for the batch input.
     private SuggestedWords getSuggestedWordsForBatchInput(final WordComposer wordComposer,
             final String prevWordForBigram, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords, final int sessionId) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+            final int sessionId) {
         final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
                 MAX_SUGGESTIONS);
 
@@ -357,7 +361,8 @@ public final class Suggest {
             }
             final Dictionary dictionary = mDictionaries.get(key);
             suggestionsSet.addAll(dictionary.getSuggestionsWithSessionId(wordComposer,
-                    prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId));
+                    prevWordForBigram, proximityInfo, blockOffensiveWords,
+                    additionalFeaturesOptions, sessionId));
         }
 
         for (SuggestedWordInfo wordInfo : suggestionsSet) {
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index 92f96c027875285c0fb0554522b3c9177a4fba8a..67ef538ac5b03dc3d7812f85ecb9d020bf488afe 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -34,9 +34,10 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB
     @Override
     public synchronized ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
             final String prevWordForBigrams, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         syncReloadDictionaryIfRequired();
-        return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords);
+        return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords,
+                additionalFeaturesOptions);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
index 33fe89611873d88d1a07900fb1bbec051e23685b..bea5223209c9c70eac08a3c2c452b0b018edc92a 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -37,9 +37,10 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic
     @Override
     public synchronized ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
             final String prevWordForBigrams, final ProximityInfo proximityInfo,
-            final boolean blockOffensiveWords) {
+            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         syncReloadDictionaryIfRequired();
-        return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords);
+        return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords,
+                additionalFeaturesOptions);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
index 7f4f5e74ae91550449bdc8cc57a946c319253aaf..d446606238f830e00c068a1154b44b93c94c50e1 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
@@ -147,9 +147,9 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
     @Override
     public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
             final String prevWord, final ProximityInfo proximityInfo,
-            boolean blockOffensiveWords) {
+            boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
         return mExpandableDictionary.getSuggestions(composer, prevWord, proximityInfo,
-                blockOffensiveWords);
+                blockOffensiveWords, additionalFeaturesOptions);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
index 139f5e2900fcfb086bc3e382681f691fd7c26ffe..6543003e80a2f0d4988def947b268501f4a7f240 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
@@ -40,8 +40,4 @@ public class AdditionalFeaturesSettingUtils {
             final SharedPreferences prefs, final int[] additionalFeaturesPreferences) {
         // do nothing.
     }
-
-    public static int[] getAdditionalNativeSuggestOptions() {
-        return Settings.getInstance().getCurrent().mAdditionalFeaturesSettingValues;
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
index 878c505bdd22d20aab1a604410cb6aeb4f38ad94..cd726c9695e083f5209a1b4863ed51f2c9add489 100644
--- a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
+++ b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
@@ -34,6 +34,9 @@ public class NativeSuggestOptions {
     }
 
     public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
+        if (additionalOptions == null) {
+            return;
+        }
         for (int i = 0; i < additionalOptions.length; i++) {
             setIntegerOption(OPTIONS_SIZE + i, additionalOptions[i]);
         }
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 6719e98daf8a7e818e146215ba9ee669b1eb6924..69f9a467f520dae228beacff5f949baef484bab1 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -301,12 +301,14 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
                 // TODO: make a spell checker option to block offensive words or not
                 final ArrayList<SuggestedWordInfo> suggestions =
                         dictInfo.mDictionary.getSuggestions(composer, prevWord,
-                                dictInfo.getProximityInfo(),
-                                true /* blockOffensiveWords */);
-                for (final SuggestedWordInfo suggestion : suggestions) {
-                    final String suggestionStr = suggestion.mWord;
-                    suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
-                            suggestionStr.length(), suggestion.mScore);
+                                dictInfo.getProximityInfo(), true /* blockOffensiveWords */,
+                                null /* additionalFeaturesOptions */);
+                if (suggestions != null) {
+                    for (final SuggestedWordInfo suggestion : suggestions) {
+                        final String suggestionStr = suggestion.mWord;
+                        suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
+                                suggestionStr.length(), suggestion.mScore);
+                    }
                 }
                 isInDict = isInDictForAnyCapitalization(dictInfo.mDictionary, text, capitalizeType);
             } finally {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index ac8f68781ec0edf2f596ae2688fa333be10fc7af..a0aed2829da65f3c2f0301de62b89a3aff43e584 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -52,7 +52,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
                 @Override
                 public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
                         final String prevWord, final ProximityInfo proximityInfo,
-                        final boolean blockOffensiveWords) {
+                        final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
                     return noSuggestions;
                 }
                 @Override