diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5e45275f8e471f04307a6142317a29a8ab43d3d5..57801e43a164999697e8035c0ef7927e8511a6f2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -84,7 +84,6 @@ import com.android.inputmethod.latin.utils.CapsModeUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
 import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.DistracterFilter;
-import com.android.inputmethod.latin.utils.DistracterFilterUtils;
 import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
 import com.android.inputmethod.latin.utils.IntentUtils;
 import com.android.inputmethod.latin.utils.JniUtils;
@@ -1747,7 +1746,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     @UsedForTesting
     /* package for test */ DistracterFilter createDistracterFilter() {
-        return DistracterFilterUtils.createDistracterFilter(this /* Context */, mKeyboardSwitcher);
+        return new DistracterFilter(this /* Context */,
+                mRichImm.getMyEnabledInputMethodSubtypeList(
+                        true /* allowsImplicitlySelectedSubtypes */));
     }
 
     public void dumpDictionaryForDebug(final String dictName) {
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
index 9ea7e217ea65a68b4cc3b75a3a3eb2ed4a6d39cc..1cf06b451fd4c4d40ddd450b4b179d67b162699f 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
@@ -16,13 +16,23 @@
 
 package com.android.inputmethod.latin.utils;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.text.InputType;
 import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.PrevWordsInfo;
 import com.android.inputmethod.latin.Suggest;
@@ -41,8 +51,10 @@ public class DistracterFilter {
     private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120;
 
     private final Context mContext;
+    private final Map<Locale, InputMethodSubtype> mLocaleToSubtypeMap;
+    private final Map<Locale, Keyboard> mLocaleToKeyboardMap;
     private final Suggest mSuggest;
-    private final Keyboard mKeyboard;
+    private Keyboard mKeyboard;
 
     // If the score of the top suggestion exceeds this value, the tested word (e.g.,
     // an OOV, a misspelling, or an in-vocabulary word) would be considered as a distracter to
@@ -51,17 +63,32 @@ public class DistracterFilter {
     // the dictionary.
     private static final float DISTRACTER_WORD_SCORE_THRESHOLD = 2.0f;
 
+    // Create empty distracter filter.
+    public DistracterFilter() {
+        this(null, new ArrayList<InputMethodSubtype>());
+    }
+
     /**
      * Create a DistracterFilter instance.
      *
      * @param context the context.
-     * @param keyboard the keyboard that is currently being used. This information is needed
-     *                 when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions.
+     * @param enabledSubtypes the enabled subtypes.
      */
-    public DistracterFilter(final Context context, final Keyboard keyboard) {
+    public DistracterFilter(final Context context, final List<InputMethodSubtype> enabledSubtypes) {
         mContext = context;
+        mLocaleToSubtypeMap = new HashMap<>();
+        for (final InputMethodSubtype subtype : enabledSubtypes) {
+            final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+            if (mLocaleToSubtypeMap.containsKey(locale)) {
+                // Multiple subtypes are enabled for one locale.
+                // TODO: Investigate what we should do for this case.
+                continue;
+            }
+            mLocaleToSubtypeMap.put(locale, subtype);
+        }
+        mLocaleToKeyboardMap = new HashMap<>();
         mSuggest = new Suggest();
-        mKeyboard = keyboard;
+        mKeyboard = null;
     }
 
     private static boolean suggestionExceedsDistracterThreshold(
@@ -78,6 +105,30 @@ public class DistracterFilter {
         return false;
     }
 
+    private void loadKeyboardForLocale(final Locale newLocale) {
+        final Keyboard cachedKeyboard = mLocaleToKeyboardMap.get(newLocale);
+        if (cachedKeyboard != null) {
+            mKeyboard = cachedKeyboard;
+            return;
+        }
+        final InputMethodSubtype subtype = mLocaleToSubtypeMap.get(newLocale);
+        if (subtype == null) {
+            return;
+        }
+        final EditorInfo editorInfo = new EditorInfo();
+        editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
+        final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
+                mContext, editorInfo);
+        final Resources res = mContext.getResources();
+        final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+        final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
+        builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
+        builder.setSubtype(subtype);
+        builder.setIsSpellChecker(false /* isSpellChecker */);
+        final KeyboardLayoutSet layoutSet = builder.build();
+        mKeyboard = layoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
+    }
+
     private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException {
         mSuggest.mDictionaryFacilitator.resetDictionaries(mContext, newlocale,
                 false /* useContactsDict */, false /* usePersonalizedDicts */,
@@ -92,15 +143,21 @@ public class DistracterFilter {
      * @param prevWordsInfo the information of previous words.
      * @param testedWord the word that will be tested to see whether it is a distracter to words
      *                   in dictionaries.
-     * @param locale the locale of words.
+     * @param locale the locale of word.
      * @return true if testedWord is a distracter, otherwise false.
      */
     public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo,
             final String testedWord, final Locale locale) {
-        if (mKeyboard == null || locale == null) {
+        if (locale == null) {
             return false;
         }
         if (!locale.equals(mSuggest.mDictionaryFacilitator.getLocale())) {
+            if (!mLocaleToSubtypeMap.containsKey(locale)) {
+                Log.e(TAG, "Locale " + locale + " is not enabled.");
+                // TODO: Investigate what we should do for disabled locales.
+                return false;
+            }
+            loadKeyboardForLocale(locale);
             // Reset dictionaries for the locale.
             try {
                 loadDictionariesForLocale(locale);
@@ -109,11 +166,12 @@ public class DistracterFilter {
                 return false;
             }
         }
-
+        if (mKeyboard == null) {
+            return false;
+        }
         final WordComposer composer = new WordComposer();
         final int[] codePoints = StringUtils.toCodePointArray(testedWord);
-        final int[] coordinates;
-        coordinates = mKeyboard.getCoordinates(codePoints);
+        final int[] coordinates = mKeyboard.getCoordinates(codePoints);
         composer.setComposingWord(codePoints, coordinates, prevWordsInfo);
 
         final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord);
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java
deleted file mode 100644
index 8a711a24eee2884a9a82cf43bbc87d0fc7a4ca8c..0000000000000000000000000000000000000000
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.content.Context;
-
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.MainKeyboardView;
-
-public class DistracterFilterUtils {
-    private DistracterFilterUtils() {
-        // This utility class is not publicly instantiable.
-    }
-
-    public static final DistracterFilter createDistracterFilter(final Context context,
-            final KeyboardSwitcher keyboardSwitcher) {
-        final MainKeyboardView mainKeyboardView = keyboardSwitcher.getMainKeyboardView();
-        // TODO: Create Keyboard when mainKeyboardView is null.
-        // TODO: Figure out the most reasonable keyboard for the filter. Refer to the
-        // spellchecker's logic.
-        final Keyboard keyboard = (mainKeyboardView != null) ?
-                mainKeyboardView.getKeyboard() : null;
-        final DistracterFilter distracterFilter = new DistracterFilter(context, keyboard);
-        return distracterFilter;
-    }
-}