diff --git a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java
index 4a44aaa94aef43ee6c12fb15326f242e9093fe77..7a5d2e68f39dda1f36b50189147bb9aaeca30451 100644
--- a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java
+++ b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java
@@ -23,7 +23,6 @@ import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.common.InputPointers;
 import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer;
 
-import java.util.List;
 import java.util.Locale;
 
 /**
@@ -39,7 +38,7 @@ public class GestureConsumer {
 
     public static GestureConsumer newInstance(
             final EditorInfo editorInfo, final PrivateCommandPerformer commandPerformer,
-            final List<Locale> locales, final Keyboard keyboard) {
+            final Locale locale, final Keyboard keyboard) {
         return GestureConsumer.NULL_GESTURE_CONSUMER;
     }
 
@@ -50,10 +49,10 @@ public class GestureConsumer {
         return false;
     }
 
-    public void onInit(final List<Locale> locales, final Keyboard keyboard) {
+    public void onInit(final Locale locale, final Keyboard keyboard) {
     }
 
-    public void onGestureStarted(final List<Locale> locales, final Keyboard keyboard) {
+    public void onGestureStarted(final Locale locale, final Keyboard keyboard) {
     }
 
     public void onGestureCanceled() {
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index d1db3d4c5e03134fd9f703533bde64277b446b3b..299d1b7c5e347ba9c309000bb81f52b34e90c494 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -287,7 +287,7 @@ public class Key implements Comparable<Key> {
         mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
                 | row.getDefaultKeyLabelFlags();
         final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
-        final Locale localeForUpcasing = params.mId.getLocales()[0];
+        final Locale localeForUpcasing = params.mId.getLocale();
         int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
         String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index d43bf37cba73591e5a94a8d11043040d59b83266..a1f7bf0e1d71a4a964899a07f724ce0a3febfde2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -164,8 +164,8 @@ public final class KeyboardId {
         return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo);
     }
 
-    public Locale[] getLocales() {
-        return mSubtype.getLocales();
+    public Locale getLocale() {
+        return mSubtype.getLocale();
     }
 
     @Override
@@ -182,7 +182,7 @@ public final class KeyboardId {
     public String toString() {
         return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s%s%s%s]",
                 elementIdToName(mElementId),
-                Arrays.deepToString(mSubtype.getLocales()),
+                mSubtype.getLocale(),
                 mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
                 mWidth, mHeight,
                 modeName(mMode),
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index fca5ecbc0ab5cb80dc58c27b32973c5919a49fe6..92e5dfceb68424aa66b296aa378d23fda09f2749 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -121,8 +121,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
         mKeyboardLayoutSet = builder.build();
         try {
             mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
-            // TODO: revisit this for multi-lingual input
-            mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocales()[0], mThemeContext);
+            mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocale(), mThemeContext);
         } catch (KeyboardLayoutSetException e) {
             Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
         }
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index ce4bb7454e2c414181630970ab07d3a8cda6585a..00d4fa236f6c9360ffd570f3055527715e5edae3 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -843,15 +843,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
     // Layout language name on spacebar.
     private String layoutLanguageOnSpacebar(final Paint paint,
             final RichInputMethodSubtype subtype, final int width) {
-        if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarUtils.FORMAT_TYPE_MULTIPLE) {
-            final Locale[] locales = subtype.getLocales();
-            final String[] languages = new String[locales.length];
-            for (int i = 0; i < locales.length; ++i) {
-                languages[i] = locales[i].getLanguage().toUpperCase(Locale.ROOT);
-            }
-            return TextUtils.join(" / ", languages);
-        }
-
         // Choose appropriate language name to fit into the width.
         if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarUtils.FORMAT_TYPE_FULL_LOCALE) {
             final String fullText = subtype.getFullDisplayName();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 2b07e1d46671e154d0ce2c2f3173eab26cb5e227..0eabf6cc91a3b4427457eb174e64fc207409033d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -281,8 +281,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
 
             params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
             params.mIconsSet.loadIcons(keyboardAttr);
-            // TODO: this needs to be revisited for multi-lingual input.
-            params.mTextsSet.setLocale(params.mId.getLocales()[0], mContext);
+            params.mTextsSet.setLocale(params.mId.getLocale(), mContext);
 
             final int resourceId = keyboardAttr.getResourceId(
                     R.styleable.Keyboard_touchPositionCorrectionData, 0);
@@ -673,10 +672,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
                     R.styleable.Keyboard_Case_imeAction, id.imeAction());
             final boolean isIconDefinedMatched = isIconDefined(caseAttr,
                     R.styleable.Keyboard_Case_isIconDefined, mParams.mIconsSet);
-            final Locale[] locales = id.getLocales();
-            final boolean localeCodeMatched = matchLocaleCodes(caseAttr, locales);
-            final boolean languageCodeMatched = matchLanguageCodes(caseAttr, locales);
-            final boolean countryCodeMatched = matchCountryCodes(caseAttr, locales);
+            final Locale locale = id.getLocale();
+            final boolean localeCodeMatched = matchLocaleCodes(caseAttr, locale);
+            final boolean languageCodeMatched = matchLanguageCodes(caseAttr, locale);
+            final boolean countryCodeMatched = matchCountryCodes(caseAttr, locale);
             final boolean splitLayoutMatched = matchBoolean(caseAttr,
                     R.styleable.Keyboard_Case_isSplitLayout, id.mIsSplitLayout);
             final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
@@ -732,21 +731,16 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
         }
     }
 
-    private static boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) {
-        // TODO: adujst this for multilingual input
-        return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString());
+    private static boolean matchLocaleCodes(TypedArray caseAttr, final Locale locale) {
+        return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locale.toString());
     }
 
-    private static boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) {
-        // TODO: adujst this for multilingual input
-        return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode,
-                locales[0].getLanguage());
+    private static boolean matchLanguageCodes(TypedArray caseAttr, Locale locale) {
+        return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, locale.getLanguage());
     }
 
-    private static boolean matchCountryCodes(TypedArray caseAttr, Locale[] locales) {
-        // TODO: adujst this for multilingual input
-        return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode,
-                locales[0].getCountry());
+    private static boolean matchCountryCodes(TypedArray caseAttr, Locale locale) {
+        return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode, locale.getCountry());
     }
 
     private static boolean matchInteger(final TypedArray a, final int index, final int value) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index b658889978a40f4ee4c5ac211a85e7042f718fef..5f981a009e943b8ad4f336ad57caafe4dbe71704 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -72,11 +72,11 @@ public interface DictionaryFacilitator {
             Dictionary.TYPE_CONTACTS};
 
     /**
-     * Returns whether this facilitator is exactly for this list of locales.
+     * Returns whether this facilitator is exactly for this locale.
      *
-     * @param locales the list of locales to test against
+     * @param locale the locale to test against
      */
-    boolean isForLocales(final Locale[] locales);
+    boolean isForLocale(final Locale locale);
 
     /**
      * Returns whether this facilitator is exactly for this account.
@@ -91,25 +91,11 @@ public interface DictionaryFacilitator {
 
     boolean isActive();
 
-    /**
-     * Returns the most probable locale among all currently active locales. BE CAREFUL using this.
-     *
-     * DO NOT USE THIS just because it's convenient. Use it when it's correct, for example when
-     * choosing what dictionary to put a word in, or when changing the capitalization of a typed
-     * string.
-     * @return the most probable locale
-     */
-    Locale getMostProbableLocale();
-
-    Locale[] getLocales();
-
-    void switchMostProbableLanguage(@Nullable final Locale locale);
-
-    boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale);
+    Locale getLocale();
 
     void resetDictionaries(
             final Context context,
-            final Locale[] newLocales,
+            final Locale newLocale,
             final boolean useContactsDict,
             final boolean usePersonalizedDicts,
             final boolean forceReloadMainDictionary,
@@ -120,7 +106,7 @@ public interface DictionaryFacilitator {
     @UsedForTesting
     void resetDictionariesForTesting(
             final Context context,
-            final Locale[] locales,
+            final Locale locale,
             final ArrayList<String> dictionaryTypes,
             final HashMap<String, File> dictionaryFiles,
             final Map<String, Map<String, String>> additionalDictAttributes,
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index e0b0b2b7e788532ce7b2f9fa07a5ea1482396b49..2f3c582516e0f49004814501aa84197f58c510c5 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -63,12 +63,8 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     // HACK: This threshold is being used when adding a capitalized entry in the User History
     // dictionary.
     private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
-    // How many words we need to type in a row ({@see mConfidenceInMostProbableLanguage}) to
-    // declare we are confident the user is typing in the most probable language.
-    private static final int CONFIDENCE_THRESHOLD = 3;
 
-    private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
-    private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0];
+    private DictionaryGroup mDictionaryGroup = new DictionaryGroup();
     private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
     // To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
     private final Object mLock = new Object();
@@ -86,28 +82,9 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
             new Class[] { Context.class, Locale.class, File.class, String.class, String.class };
 
-    /**
-     * Returns whether this facilitator is exactly for this list of locales.
-     *
-     * @param locales the list of locales to test against
-     */
-    public boolean isForLocales(final Locale[] locales) {
-        if (locales.length != mDictionaryGroups.length) {
-            return false;
-        }
-        for (final Locale locale : locales) {
-            boolean found = false;
-            for (final DictionaryGroup group : mDictionaryGroups) {
-                if (locale.equals(group.mLocale)) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                return false;
-            }
-        }
-        return true;
+    @Override
+    public boolean isForLocale(final Locale locale) {
+        return locale != null && locale.equals(mDictionaryGroup.mLocale);
     }
 
     /**
@@ -116,12 +93,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
      * @param account the account to test against.
      */
     public boolean isForAccount(@Nullable final String account) {
-        for (final DictionaryGroup group : mDictionaryGroups) {
-            if (!TextUtils.equals(group.mAccount, account)) {
-                return false;
-            }
-        }
-        return true;
+        return TextUtils.equals(mDictionaryGroup.mAccount, account);
     }
 
     /**
@@ -231,75 +203,12 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     }
 
     public boolean isActive() {
-        return null != mDictionaryGroups[0].mLocale;
-    }
-
-    /**
-     * Returns the most probable locale among all currently active locales. BE CAREFUL using this.
-     *
-     * DO NOT USE THIS just because it's convenient. Use it when it's correct, for example when
-     * choosing what dictionary to put a word in, or when changing the capitalization of a typed
-     * string.
-     * @return the most probable locale
-     */
-    public Locale getMostProbableLocale() {
-        return getDictionaryGroupForMostProbableLanguage().mLocale;
-    }
-
-    public Locale[] getLocales() {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        final Locale[] locales = new Locale[dictionaryGroups.length];
-        for (int i = 0; i < dictionaryGroups.length; ++i) {
-            locales[i] = dictionaryGroups[i].mLocale;
-        }
-        return locales;
+        return mDictionaryGroup.mLocale != null;
     }
 
-    private DictionaryGroup getDictionaryGroupForMostProbableLanguage() {
-        return mMostProbableDictionaryGroup;
-    }
-
-    public void switchMostProbableLanguage(@Nullable final Locale locale) {
-        if (null == locale) {
-            // In many cases, there is no locale to a committed word. For example, a typed word
-            // that is in none of the currently active dictionaries but still does not
-            // auto-correct to anything has no locale. In this case we simply do not change
-            // the most probable language and do not touch confidence.
-            return;
-        }
-        final DictionaryGroup newMostProbableDictionaryGroup =
-                findDictionaryGroupWithLocale(mDictionaryGroups, locale);
-        if (null == newMostProbableDictionaryGroup) {
-            // It seems this may happen as a race condition; pressing the globe key and space
-            // in quick succession could commit a word out of a dictionary that's not in the
-            // facilitator any more. In this case, just not changing things is fine.
-            return;
-        }
-        if (newMostProbableDictionaryGroup == mMostProbableDictionaryGroup) {
-            ++newMostProbableDictionaryGroup.mConfidence;
-        } else {
-            mMostProbableDictionaryGroup.mWeightForTypingInLocale =
-                    DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE;
-            mMostProbableDictionaryGroup.mWeightForGesturingInLocale =
-                    DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE;
-            mMostProbableDictionaryGroup.mConfidence = 0;
-            newMostProbableDictionaryGroup.mWeightForTypingInLocale =
-                    DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
-            newMostProbableDictionaryGroup.mWeightForGesturingInLocale =
-                    DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
-            mMostProbableDictionaryGroup = newMostProbableDictionaryGroup;
-        }
-    }
-
-    public boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale) {
-        final DictionaryGroup mostProbableDictionaryGroup = mMostProbableDictionaryGroup;
-        if (!mostProbableDictionaryGroup.mLocale.equals(mLocale)) {
-            return false;
-        }
-        if (mDictionaryGroups.length <= 1) {
-            return true;
-        }
-        return mostProbableDictionaryGroup.mConfidence >= CONFIDENCE_THRESHOLD;
+    @Override
+    public Locale getLocale() {
+        return mDictionaryGroup.mLocale;
     }
 
     @Nullable
@@ -325,19 +234,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     }
 
     @Nullable
-    static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
+    static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup dictionaryGroup,
             final Locale locale) {
-        for (DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            if (locale.equals(dictionaryGroup.mLocale)) {
-                return dictionaryGroup;
-            }
-        }
-        return null;
+        return locale.equals(dictionaryGroup.mLocale) ? dictionaryGroup : null;
     }
 
+    @Override
     public void resetDictionaries(
             final Context context,
-            final Locale[] newLocales,
+            final Locale newLocale,
             final boolean useContactsDict,
             final boolean usePersonalizedDicts,
             final boolean forceReloadMainDictionary,
@@ -356,14 +261,11 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
         }
 
         // Gather all dictionaries. We'll remove them from the list to clean up later.
-        for (final Locale newLocale : newLocales) {
-            final ArrayList<String> dictTypeForLocale = new ArrayList<>();
-            existingDictionariesToCleanup.put(newLocale, dictTypeForLocale);
-            final DictionaryGroup currentDictionaryGroupForLocale =
-                    findDictionaryGroupWithLocale(mDictionaryGroups, newLocale);
-            if (null == currentDictionaryGroupForLocale) {
-                continue;
-            }
+        final ArrayList<String> dictTypeForLocale = new ArrayList<>();
+        existingDictionariesToCleanup.put(newLocale, dictTypeForLocale);
+        final DictionaryGroup currentDictionaryGroupForLocale =
+                findDictionaryGroupWithLocale(mDictionaryGroup, newLocale);
+        if (currentDictionaryGroupForLocale != null) {
             for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
                 if (currentDictionaryGroupForLocale.hasDict(dictType, account)) {
                     dictTypeForLocale.add(dictType);
@@ -374,50 +276,46 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             }
         }
 
-        final DictionaryGroup[] newDictionaryGroups = new DictionaryGroup[newLocales.length];
-        for (int i = 0; i < newLocales.length; ++i) {
-            final Locale newLocale = newLocales[i];
-            final DictionaryGroup dictionaryGroupForLocale =
-                    findDictionaryGroupWithLocale(mDictionaryGroups, newLocale);
-            final ArrayList<String> dictTypesToCleanupForLocale =
-                    existingDictionariesToCleanup.get(newLocale);
-            final boolean noExistingDictsForThisLocale = (null == dictionaryGroupForLocale);
+        final DictionaryGroup dictionaryGroupForLocale =
+                findDictionaryGroupWithLocale(mDictionaryGroup, newLocale);
+        final ArrayList<String> dictTypesToCleanupForLocale =
+                existingDictionariesToCleanup.get(newLocale);
+        final boolean noExistingDictsForThisLocale = (null == dictionaryGroupForLocale);
 
-            final Dictionary mainDict;
-            if (forceReloadMainDictionary || noExistingDictsForThisLocale
-                    || !dictionaryGroupForLocale.hasDict(Dictionary.TYPE_MAIN, account)) {
-                mainDict = null;
-            } else {
-                mainDict = dictionaryGroupForLocale.getDict(Dictionary.TYPE_MAIN);
-                dictTypesToCleanupForLocale.remove(Dictionary.TYPE_MAIN);
-            }
+        final Dictionary mainDict;
+        if (forceReloadMainDictionary || noExistingDictsForThisLocale
+                || !dictionaryGroupForLocale.hasDict(Dictionary.TYPE_MAIN, account)) {
+            mainDict = null;
+        } else {
+            mainDict = dictionaryGroupForLocale.getDict(Dictionary.TYPE_MAIN);
+            dictTypesToCleanupForLocale.remove(Dictionary.TYPE_MAIN);
+        }
 
-            final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
-            for (final String subDictType : subDictTypesToUse) {
-                final ExpandableBinaryDictionary subDict;
-                if (noExistingDictsForThisLocale
-                        || !dictionaryGroupForLocale.hasDict(subDictType, account)) {
-                    // Create a new dictionary.
-                    subDict = getSubDict(subDictType, context, newLocale, null /* dictFile */,
-                            dictNamePrefix, account);
-                } else {
-                    // Reuse the existing dictionary, and don't close it at the end
-                    subDict = dictionaryGroupForLocale.getSubDict(subDictType);
-                    dictTypesToCleanupForLocale.remove(subDictType);
-                }
-                subDicts.put(subDictType, subDict);
+        final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
+        for (final String subDictType : subDictTypesToUse) {
+            final ExpandableBinaryDictionary subDict;
+            if (noExistingDictsForThisLocale
+                    || !dictionaryGroupForLocale.hasDict(subDictType, account)) {
+                // Create a new dictionary.
+                subDict = getSubDict(subDictType, context, newLocale, null /* dictFile */,
+                        dictNamePrefix, account);
+            } else {
+                // Reuse the existing dictionary, and don't close it at the end
+                subDict = dictionaryGroupForLocale.getSubDict(subDictType);
+                dictTypesToCleanupForLocale.remove(subDictType);
             }
-            newDictionaryGroups[i] = new DictionaryGroup(newLocale, mainDict, account, subDicts);
+            subDicts.put(subDictType, subDict);
         }
+        DictionaryGroup newDictionaryGroup =
+                new DictionaryGroup(newLocale, mainDict, account, subDicts);
 
         // Replace Dictionaries.
-        final DictionaryGroup[] oldDictionaryGroups;
+        final DictionaryGroup oldDictionaryGroup;
         synchronized (mLock) {
-            oldDictionaryGroups = mDictionaryGroups;
-            mDictionaryGroups = newDictionaryGroups;
-            mMostProbableDictionaryGroup = newDictionaryGroups[0];
+            oldDictionaryGroup = mDictionaryGroup;
+            mDictionaryGroup = newDictionaryGroup;
             if (hasAtLeastOneUninitializedMainDictionary()) {
-                asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
+                asyncReloadUninitializedMainDictionaries(context, newLocale, listener);
             }
         }
         if (listener != null) {
@@ -429,7 +327,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             final ArrayList<String> dictTypesToCleanUp =
                     existingDictionariesToCleanup.get(localeToCleanUp);
             final DictionaryGroup dictionarySetToCleanup =
-                    findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
+                    findDictionaryGroupWithLocale(oldDictionaryGroup, localeToCleanUp);
             for (final String dictType : dictTypesToCleanUp) {
                 dictionarySetToCleanup.closeDict(dictType);
             }
@@ -437,123 +335,105 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     }
 
     private void asyncReloadUninitializedMainDictionaries(final Context context,
-            final Locale[] locales, final DictionaryInitializationListener listener) {
+            final Locale locale, final DictionaryInitializationListener listener) {
         final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
         mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
         ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
             @Override
             public void run() {
                 doReloadUninitializedMainDictionaries(
-                        context, locales, listener, latchForWaitingLoadingMainDictionary);
+                        context, locale, listener, latchForWaitingLoadingMainDictionary);
             }
         });
     }
 
-    void doReloadUninitializedMainDictionaries(final Context context, final Locale[] locales,
+    void doReloadUninitializedMainDictionaries(final Context context, final Locale locale,
             final DictionaryInitializationListener listener,
             final CountDownLatch latchForWaitingLoadingMainDictionary) {
-        for (final Locale locale : locales) {
-            final DictionaryGroup dictionaryGroup =
-                    findDictionaryGroupWithLocale(mDictionaryGroups, locale);
-            if (null == dictionaryGroup) {
-                // This should never happen, but better safe than crashy
-                Log.w(TAG, "Expected a dictionary group for " + locale + " but none found");
-                continue;
-            }
-            final Dictionary mainDict =
-                    DictionaryFactory.createMainDictionaryFromManager(context, locale);
-            synchronized (mLock) {
-                if (locale.equals(dictionaryGroup.mLocale)) {
-                    dictionaryGroup.setMainDict(mainDict);
-                } else {
-                    // Dictionary facilitator has been reset for another locale.
-                    mainDict.close();
-                }
+        final DictionaryGroup dictionaryGroup =
+                findDictionaryGroupWithLocale(mDictionaryGroup, locale);
+        if (null == dictionaryGroup) {
+            // This should never happen, but better safe than crashy
+            Log.w(TAG, "Expected a dictionary group for " + locale + " but none found");
+            return;
+        }
+        final Dictionary mainDict =
+                DictionaryFactory.createMainDictionaryFromManager(context, locale);
+        synchronized (mLock) {
+            if (locale.equals(dictionaryGroup.mLocale)) {
+                dictionaryGroup.setMainDict(mainDict);
+            } else {
+                // Dictionary facilitator has been reset for another locale.
+                mainDict.close();
             }
         }
         if (listener != null) {
-            listener.onUpdateMainDictionaryAvailability(
-                    hasAtLeastOneInitializedMainDictionary());
+            listener.onUpdateMainDictionaryAvailability(hasAtLeastOneInitializedMainDictionary());
         }
         latchForWaitingLoadingMainDictionary.countDown();
     }
 
     @UsedForTesting
-    public void resetDictionariesForTesting(final Context context, final Locale[] locales,
+    public void resetDictionariesForTesting(final Context context, final Locale locale,
             final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
             final Map<String, Map<String, String>> additionalDictAttributes,
             @Nullable final String account) {
         Dictionary mainDictionary = null;
         final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
 
-        final DictionaryGroup[] dictionaryGroups = new DictionaryGroup[locales.length];
-        for (int i = 0; i < locales.length; ++i) {
-            final Locale locale = locales[i];
-            for (final String dictType : dictionaryTypes) {
-                if (dictType.equals(Dictionary.TYPE_MAIN)) {
-                    mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context,
-                            locale);
-                } else {
-                    final File dictFile = dictionaryFiles.get(dictType);
-                    final ExpandableBinaryDictionary dict = getSubDict(
-                            dictType, context, locale, dictFile, "" /* dictNamePrefix */, account);
-                    if (additionalDictAttributes.containsKey(dictType)) {
-                        dict.clearAndFlushDictionaryWithAdditionalAttributes(
-                                additionalDictAttributes.get(dictType));
-                    }
-                    if (dict == null) {
-                        throw new RuntimeException("Unknown dictionary type: " + dictType);
-                    }
-                    dict.reloadDictionaryIfRequired();
-                    dict.waitAllTasksForTests();
-                    subDicts.put(dictType, dict);
+        for (final String dictType : dictionaryTypes) {
+            if (dictType.equals(Dictionary.TYPE_MAIN)) {
+                mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context,
+                        locale);
+            } else {
+                final File dictFile = dictionaryFiles.get(dictType);
+                final ExpandableBinaryDictionary dict = getSubDict(
+                        dictType, context, locale, dictFile, "" /* dictNamePrefix */, account);
+                if (additionalDictAttributes.containsKey(dictType)) {
+                    dict.clearAndFlushDictionaryWithAdditionalAttributes(
+                            additionalDictAttributes.get(dictType));
                 }
+                if (dict == null) {
+                    throw new RuntimeException("Unknown dictionary type: " + dictType);
+                }
+                dict.reloadDictionaryIfRequired();
+                dict.waitAllTasksForTests();
+                subDicts.put(dictType, dict);
             }
-            dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, account, subDicts);
         }
-        mDictionaryGroups = dictionaryGroups;
-        mMostProbableDictionaryGroup = dictionaryGroups[0];
+        mDictionaryGroup = new DictionaryGroup(locale, mainDictionary, account, subDicts);
     }
 
     public void closeDictionaries() {
-        final DictionaryGroup[] dictionaryGroups;
+        final DictionaryGroup dictionaryGroupToClose;
         synchronized (mLock) {
-            dictionaryGroups = mDictionaryGroups;
-            mMostProbableDictionaryGroup = new DictionaryGroup();
-            mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
+            dictionaryGroupToClose = mDictionaryGroup;
+            mDictionaryGroup = new DictionaryGroup();
         }
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : ALL_DICTIONARY_TYPES) {
-                dictionaryGroup.closeDict(dictType);
-            }
+        for (final String dictType : ALL_DICTIONARY_TYPES) {
+            dictionaryGroupToClose.closeDict(dictType);
         }
     }
 
     @UsedForTesting
     public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
-        return mMostProbableDictionaryGroup.getSubDict(dictName);
+        return mDictionaryGroup.getSubDict(dictName);
     }
 
     // The main dictionaries are loaded asynchronously.  Don't cache the return value
     // of these methods.
     public boolean hasAtLeastOneInitializedMainDictionary() {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            final Dictionary mainDict = dictionaryGroup.getDict(Dictionary.TYPE_MAIN);
-            if (mainDict != null && mainDict.isInitialized()) {
-                return true;
-            }
+        final Dictionary mainDict = mDictionaryGroup.getDict(Dictionary.TYPE_MAIN);
+        if (mainDict != null && mainDict.isInitialized()) {
+            return true;
         }
         return false;
     }
 
     public boolean hasAtLeastOneUninitializedMainDictionary() {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            final Dictionary mainDict = dictionaryGroup.getDict(Dictionary.TYPE_MAIN);
-            if (mainDict == null || !mainDict.isInitialized()) {
-                return true;
-            }
+        final Dictionary mainDict = mDictionaryGroup.getDict(Dictionary.TYPE_MAIN);
+        if (mainDict == null || !mainDict.isInitialized()) {
+            return true;
         }
         return false;
     }
@@ -567,25 +447,22 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
             throws InterruptedException {
         waitForLoadingMainDictionaries(timeout, unit);
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final ExpandableBinaryDictionary dict : dictionaryGroup.mSubDictMap.values()) {
-                dict.waitAllTasksForTests();
-            }
+        for (final ExpandableBinaryDictionary dict : mDictionaryGroup.mSubDictMap.values()) {
+            dict.waitAllTasksForTests();
         }
     }
 
     public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
             @Nonnull final NgramContext ngramContext, final long timeStampInSeconds,
             final boolean blockPotentiallyOffensive) {
-        final DictionaryGroup dictionaryGroup = getDictionaryGroupForMostProbableLanguage();
         final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
         NgramContext ngramContextForCurrentWord = ngramContext;
         for (int i = 0; i < words.length; i++) {
             final String currentWord = words[i];
             final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false;
-            addWordToUserHistory(dictionaryGroup, ngramContextForCurrentWord, currentWord,
-                    wasCurrentWordAutoCapitalized, (int) timeStampInSeconds, blockPotentiallyOffensive);
+            addWordToUserHistory(mDictionaryGroup, ngramContextForCurrentWord, currentWord,
+                    wasCurrentWordAutoCapitalized, (int) timeStampInSeconds,
+                    blockPotentiallyOffensive);
             ngramContextForCurrentWord =
                     ngramContextForCurrentWord.getNextNgramContext(new WordInfo(currentWord));
         }
@@ -596,8 +473,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
         final ExpandableBinaryDictionary userHistoryDictionary =
                 dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY);
-        if (userHistoryDictionary == null
-                || !isConfidentAboutCurrentLanguageBeing(userHistoryDictionary.mLocale)) {
+        if (userHistoryDictionary == null || !isForLocale(userHistoryDictionary.mLocale)) {
             return;
         }
         final int maxFreq = getFrequency(word);
@@ -644,8 +520,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
     }
 
     private void removeWord(final String dictName, final String word) {
-        final ExpandableBinaryDictionary dictionary =
-                getDictionaryGroupForMostProbableLanguage().getSubDict(dictName);
+        final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictName);
         if (dictionary != null) {
             dictionary.removeUnigramEntryDynamically(word);
         }
@@ -668,28 +543,25 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             SettingsValuesForSuggestion settingsValuesForSuggestion, int sessionId,
             int inputStyle) {
         long proximityInfoHandle = keyboard.getProximityInfo().getNativeProximityInfo();
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
         final SuggestionResults suggestionResults = new SuggestionResults(
                 SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext(),
                 false /* firstSuggestionExceedsConfidenceThreshold */);
         final float[] weightOfLangModelVsSpatialModel =
                 new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICTIONARY_TYPES_FOR_SUGGESTIONS) {
-                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
-                if (null == dictionary) continue;
-                final float weightForLocale = composedData.mIsBatchMode
-                        ? dictionaryGroup.mWeightForGesturingInLocale
-                        : dictionaryGroup.mWeightForTypingInLocale;
-                final ArrayList<SuggestedWordInfo> dictionarySuggestions =
-                        dictionary.getSuggestions(composedData, ngramContext,
-                                proximityInfoHandle, settingsValuesForSuggestion, sessionId,
-                                weightForLocale, weightOfLangModelVsSpatialModel);
-                if (null == dictionarySuggestions) continue;
-                suggestionResults.addAll(dictionarySuggestions);
-                if (null != suggestionResults.mRawSuggestions) {
-                    suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
-                }
+        for (final String dictType : DICTIONARY_TYPES_FOR_SUGGESTIONS) {
+            final Dictionary dictionary = mDictionaryGroup.getDict(dictType);
+            if (null == dictionary) continue;
+            final float weightForLocale = composedData.mIsBatchMode
+                    ? mDictionaryGroup.mWeightForGesturingInLocale
+                    : mDictionaryGroup.mWeightForTypingInLocale;
+            final ArrayList<SuggestedWordInfo> dictionarySuggestions =
+                    dictionary.getSuggestions(composedData, ngramContext,
+                            proximityInfoHandle, settingsValuesForSuggestion, sessionId,
+                            weightForLocale, weightOfLangModelVsSpatialModel);
+            if (null == dictionarySuggestions) continue;
+            suggestionResults.addAll(dictionarySuggestions);
+            if (null != suggestionResults.mRawSuggestions) {
+                suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
             }
         }
         return suggestionResults;
@@ -707,20 +579,17 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
         if (TextUtils.isEmpty(word)) {
             return false;
         }
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            if (dictionaryGroup.mLocale == null) {
-                continue;
-            }
-            for (final String dictType : dictionariesToCheck) {
-                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
-                // Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
-                // would be immutable once it's finished initializing, but concretely a null test is
-                // probably good enough for the time being.
-                if (null == dictionary) continue;
-                if (dictionary.isValidWord(word)) {
-                    return true;
-                }
+        if (mDictionaryGroup.mLocale == null) {
+            return false;
+        }
+        for (final String dictType : dictionariesToCheck) {
+            final Dictionary dictionary = mDictionaryGroup.getDict(dictType);
+            // Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
+            // would be immutable once it's finished initializing, but concretely a null test is
+            // probably good enough for the time being.
+            if (null == dictionary) continue;
+            if (dictionary.isValidWord(word)) {
+                return true;
             }
         }
         return false;
@@ -731,27 +600,21 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
             return Dictionary.NOT_A_PROBABILITY;
         }
         int maxFreq = Dictionary.NOT_A_PROBABILITY;
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : ALL_DICTIONARY_TYPES) {
-                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
-                if (dictionary == null) continue;
-                final int tempFreq = dictionary.getFrequency(word);
-                if (tempFreq >= maxFreq) {
-                    maxFreq = tempFreq;
-                }
+        for (final String dictType : ALL_DICTIONARY_TYPES) {
+            final Dictionary dictionary = mDictionaryGroup.getDict(dictType);
+            if (dictionary == null) continue;
+            final int tempFreq = dictionary.getFrequency(word);
+            if (tempFreq >= maxFreq) {
+                maxFreq = tempFreq;
             }
         }
         return maxFreq;
     }
 
     private void clearSubDictionary(final String dictName) {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictName);
-            if (dictionary != null) {
-                dictionary.clear();
-            }
+        final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictName);
+        if (dictionary != null) {
+            dictionary.clear();
         }
     }
 
@@ -762,28 +625,22 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
 
     @Override
     public void dumpDictionaryForDebug(final String dictName) {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            final ExpandableBinaryDictionary dictToDump = dictionaryGroup.getSubDict(dictName);
-            if (dictToDump == null) {
-                Log.e(TAG, "Cannot dump " + dictName + ". "
-                        + "The dictionary is not being used for suggestion or cannot be dumped.");
-                return;
-            }
-            dictToDump.dumpAllWordsForDebug();
+        final ExpandableBinaryDictionary dictToDump = mDictionaryGroup.getSubDict(dictName);
+        if (dictToDump == null) {
+            Log.e(TAG, "Cannot dump " + dictName + ". "
+                    + "The dictionary is not being used for suggestion or cannot be dumped.");
+            return;
         }
+        dictToDump.dumpAllWordsForDebug();
     }
 
     @Override
     public ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts() {
         final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
-                final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictType);
-                if (dictionary == null) continue;
-                statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
-            }
+        for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
+            final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictType);
+            if (dictionary == null) continue;
+            statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
         }
         return statsOfEnabledSubDicts;
     }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
index 2a1ae36847d91fe7e40543feb5965c002d73146d..cbaf6ea4e9e7472cc9f85eb87662bc3e17cd7baa 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
@@ -68,7 +68,7 @@ public class DictionaryFacilitatorLruCache {
         // Nothing to do if the locale is null.  This would be the case before any get() calls.
         if (mLocale != null) {
           // Note: Given that personalized dictionaries are not used here; we can pass null account.
-          mDictionaryFacilitator.resetDictionaries(mContext, new Locale[]{mLocale},
+          mDictionaryFacilitator.resetDictionaries(mContext, mLocale,
               mUseContactsDictionary, false /* usePersonalizedDicts */,
               false /* forceReloadMainDictionary */, null /* account */,
               mDictionaryNamePrefix, null /* listener */);
@@ -89,7 +89,7 @@ public class DictionaryFacilitatorLruCache {
 
     public DictionaryFacilitator get(final Locale locale) {
         synchronized (mLock) {
-            if (!mDictionaryFacilitator.isForLocales(new Locale[]{locale})) {
+            if (!mDictionaryFacilitator.isForLocale(locale)) {
                 mLocale = locale;
                 resetDictionariesForLocaleLocked();
             }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4ae47f3778791b71a70dcf68eee60630165b23b7..a0e55c65fbe64b3698b474afd5881dd66320236d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -588,19 +588,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     // Has to be package-visible for unit tests
     @UsedForTesting
     void loadSettings() {
-        final Locale[] locales = mRichImm.getCurrentSubtypeLocales();
+        final Locale locale = mRichImm.getCurrentSubtypeLocale();
         final EditorInfo editorInfo = getCurrentInputEditorInfo();
         final InputAttributes inputAttributes = new InputAttributes(
                 editorInfo, isFullscreenMode(), getPackageName());
-        // TODO: pass the array instead
-        mSettings.loadSettings(this, locales[0], inputAttributes);
+        mSettings.loadSettings(this, locale, inputAttributes);
         final SettingsValues currentSettingsValues = mSettings.getCurrent();
         AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues);
         // This method is called on startup and language switch, before the new layout has
         // been displayed. Opening dictionaries never affects responsivity as dictionaries are
         // asynchronously loaded.
         if (!mHandler.hasPendingReopenDictionaries()) {
-            resetDictionaryFacilitator(locales);
+            resetDictionaryFacilitator(locale);
         }
         refreshPersonalizationDictionarySession(currentSettingsValues);
         resetDictionaryFacilitatorIfNecessary();
@@ -630,35 +629,35 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     }
 
     void resetDictionaryFacilitatorIfNecessary() {
-        final Locale[] subtypeSwitcherLocales = mRichImm.getCurrentSubtypeLocales();
-        if (mDictionaryFacilitator.isForLocales(subtypeSwitcherLocales)
-                && mDictionaryFacilitator.isForAccount(mSettings.getCurrent().mAccount)) {
-            return;
-        }
-        final Locale[] subtypeLocales;
-        if (0 == subtypeSwitcherLocales.length) {
+        final Locale subtypeSwitcherLocale = mRichImm.getCurrentSubtypeLocale();
+        final Locale subtypeLocale;
+        if (subtypeSwitcherLocale == null) {
             // This happens in very rare corner cases - for example, immediately after a switch
             // to LatinIME has been requested, about a frame later another switch happens. In this
             // case, we are about to go down but we still don't know it, however the system tells
             // us there is no current subtype.
             Log.e(TAG, "System is reporting no current subtype.");
-            subtypeLocales = new Locale[] { getResources().getConfiguration().locale };
+            subtypeLocale = getResources().getConfiguration().locale;
         } else {
-            subtypeLocales = subtypeSwitcherLocales;
+            subtypeLocale = subtypeSwitcherLocale;
+        }
+        if (mDictionaryFacilitator.isForLocale(subtypeLocale)
+                && mDictionaryFacilitator.isForAccount(mSettings.getCurrent().mAccount)) {
+            return;
         }
-        resetDictionaryFacilitator(subtypeLocales);
+        resetDictionaryFacilitator(subtypeLocale);
     }
 
     /**
-     * Reset the facilitator by loading dictionaries for the locales and
+     * Reset the facilitator by loading dictionaries for the given locale and
      * the current settings values.
      *
-     * @param locales the locales
+     * @param locale the locale
      */
     // TODO: make sure the current settings always have the right locales, and read from them.
-    private void resetDictionaryFacilitator(final Locale[] locales) {
+    private void resetDictionaryFacilitator(final Locale locale) {
         final SettingsValues settingsValues = mSettings.getCurrent();
-        mDictionaryFacilitator.resetDictionaries(this /* context */, locales,
+        mDictionaryFacilitator.resetDictionaries(this /* context */, locale,
                 settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
                 false /* forceReloadMainDictionary */,
                 settingsValues.mAccount, "" /* dictNamePrefix */,
@@ -676,7 +675,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     /* package private */ void resetSuggestMainDict() {
         final SettingsValues settingsValues = mSettings.getCurrent();
         mDictionaryFacilitator.resetDictionaries(this /* context */,
-                mDictionaryFacilitator.getLocales(), settingsValues.mUseContactsDict,
+                mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict,
                 settingsValues.mUsePersonalizedDicts,
                 true /* forceReloadMainDictionary */,
                 settingsValues.mAccount, "" /* dictNamePrefix */,
@@ -843,7 +842,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // Update to a gesture consumer with the current editor and IME state.
         mGestureConsumer = GestureConsumer.newInstance(editorInfo,
                 mInputLogic.getPrivateCommandPerformer(),
-                Arrays.asList(mRichImm.getCurrentSubtypeLocales()),
+                mRichImm.getCurrentSubtypeLocale(),
                 switcher.getKeyboard());
 
         // Forward this event to the accessibility utilities, if enabled.
@@ -1379,7 +1378,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     public void onStartBatchInput() {
         mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
         mGestureConsumer.onGestureStarted(
-                Arrays.asList(mRichImm.getCurrentSubtypeLocales()),
+                mRichImm.getCurrentSubtypeLocale(),
                 mKeyboardSwitcher.getKeyboard());
     }
 
@@ -1767,23 +1766,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     // TODO: can this be removed somehow without breaking the tests?
     @UsedForTesting
-    /* package for test */ SuggestedWords getSuggestedWordsForTest() {
+    SuggestedWords getSuggestedWordsForTest() {
         // You may not use this method for anything else than debug
         return DebugFlags.DEBUG_ENABLED ? mInputLogic.mSuggestedWords : null;
     }
 
     // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME.
     @UsedForTesting
-    /* package for test */ void waitForLoadingDictionaries(final long timeout, final TimeUnit unit)
+    void waitForLoadingDictionaries(final long timeout, final TimeUnit unit)
             throws InterruptedException {
         mDictionaryFacilitator.waitForLoadingDictionariesForTesting(timeout, unit);
     }
 
     // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
     @UsedForTesting
-    /* package for test */ void replaceDictionariesForTest(final Locale locale) {
+    void replaceDictionariesForTest(final Locale locale) {
         final SettingsValues settingsValues = mSettings.getCurrent();
-        mDictionaryFacilitator.resetDictionaries(this, new Locale[] { locale },
+        mDictionaryFacilitator.resetDictionaries(this, locale,
             settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
             false /* forceReloadMainDictionary */,
             settingsValues.mAccount, "", /* dictionaryNamePrefix */
@@ -1792,12 +1791,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     // DO NOT USE THIS for any other purpose than testing.
     @UsedForTesting
-    /* package for test */ void clearPersonalizedDictionariesForTest() {
+    void clearPersonalizedDictionariesForTest() {
         mDictionaryFacilitator.clearUserHistoryDictionary(this);
     }
 
     @UsedForTesting
-    /* package for test */ List<InputMethodSubtype> getEnabledSubtypesForTest() {
+    List<InputMethodSubtype> getEnabledSubtypesForTest() {
         return (mRichImm != null) ? mRichImm.getMyEnabledInputMethodSubtypeList(
                 true /* allowsImplicitlySelectedSubtypes */) : new ArrayList<InputMethodSubtype>();
     }
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 602205b59673288bf019c58502c0b7dfffc2e473..ef946c8bc9f1699f0cbdefeb05c50a808e0a7128 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -334,11 +334,11 @@ public class RichInputMethodManager {
     }
 
     @Nonnull
-    public Locale[] getCurrentSubtypeLocales() {
+    public Locale getCurrentSubtypeLocale() {
         if (null != sForcedSubtypeForTesting) {
-            return sForcedSubtypeForTesting.getLocales();
+            return sForcedSubtypeForTesting.getLocale();
         }
-        return getCurrentSubtype().getLocales();
+        return getCurrentSubtype().getLocale();
     }
 
     @Nonnull
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
index 8734e592529570885bc538f362837173822ab330..c7bd88933a07704b09dfad71b9e43d48374eba01 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
@@ -26,7 +26,6 @@ import com.android.inputmethod.latin.common.Constants;
 import com.android.inputmethod.latin.common.LocaleUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
-import java.util.Arrays;
 import java.util.Locale;
 
 import javax.annotation.Nonnull;
@@ -43,14 +42,11 @@ public final class RichInputMethodSubtype {
     @Nonnull
     private final InputMethodSubtype mSubtype;
     @Nonnull
-    private final Locale[] mLocales;
+    private final Locale mLocale;
 
-    public RichInputMethodSubtype(@Nonnull final InputMethodSubtype subtype,
-            @Nonnull final Locale... locales) {
+    public RichInputMethodSubtype(@Nonnull final InputMethodSubtype subtype) {
         mSubtype = subtype;
-        mLocales = new Locale[locales.length + 1];
-        mLocales[0] = LocaleUtils.constructLocaleFromString(mSubtype.getLocale());
-        System.arraycopy(locales, 0, mLocales, 1, locales.length);
+        mLocale = LocaleUtils.constructLocaleFromString(mSubtype.getLocale());
     }
 
     // Extra values are determined by the primary subtype. This is probably right, but
@@ -65,9 +61,6 @@ public final class RichInputMethodSubtype {
     }
 
     public boolean isNoLanguage() {
-        if (mLocales.length > 1) {
-            return false;
-        }
         return SubtypeLocaleUtils.NO_LANGUAGE.equals(mSubtype.getLocale());
     }
 
@@ -116,27 +109,27 @@ public final class RichInputMethodSubtype {
             return false;
         }
         final RichInputMethodSubtype other = (RichInputMethodSubtype)o;
-        return mSubtype.equals(other.mSubtype) && Arrays.equals(mLocales, other.mLocales);
+        return mSubtype.equals(other.mSubtype) && mLocale.equals(other.mLocale);
     }
 
     @Override
     public int hashCode() {
-        return mSubtype.hashCode() + Arrays.hashCode(mLocales);
+        return mSubtype.hashCode() + mLocale.hashCode();
     }
 
     @Override
     public String toString() {
-        return "Multi-lingual subtype: " + mSubtype.toString() + ", " + Arrays.toString(mLocales);
+        return "Multi-lingual subtype: " + mSubtype + ", " + mLocale;
     }
 
     @Nonnull
-    public Locale[] getLocales() {
-        return mLocales;
+    public Locale getLocale() {
+        return mLocale;
     }
 
     public boolean isRtlSubtype() {
         // The subtype is considered RTL if the language of the main subtype is RTL.
-        return LocaleUtils.isRtlLanguage(mLocales[0]);
+        return LocaleUtils.isRtlLanguage(mLocale);
     }
 
     // TODO: remove this method
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index f4680fc88ab1bd7e2374d7de3362baafe60ef2d1..6a0d6be9c162473fc8ef266657314f671ac663db 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -176,13 +176,13 @@ public final class Suggest {
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
                 wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
                 settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction);
-        final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
+        final Locale locale = mDictionaryFacilitator.getLocale();
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
                         trailingSingleQuotesCount,
                         // For transforming suggestions that don't come for any dictionary, we
                         // use the currently most probable locale as it's our best bet.
-                        mostProbableLocale);
+                        locale);
 
         boolean typedWordExistsInAnotherLanguage = false;
         int qualityOfFoundSourceDictionary = QUALITY_NO_MATCH;
@@ -191,7 +191,7 @@ public final class Suggest {
             // Search for the best dictionary, defined as the first one with the highest match
             // quality we can find.
             if (typedWordString.equals(info.mWord)) {
-                if (mostProbableLocale.equals(info.mSourceDict.mLocale)) {
+                if (locale.equals(info.mSourceDict.mLocale)) {
                     if (qualityOfFoundSourceDictionary < QUALITY_MATCH_PREFERRED_LOCALE) {
                         // Use this source if the old match had lower quality than this match
                         sourceDictionaryOfRemovedWord = info.mSourceDict;
@@ -217,8 +217,7 @@ public final class Suggest {
                 getWhitelistedWordInfoOrNull(suggestionsContainer);
         final String whitelistedWord;
         if (null != whitelistedWordInfo &&
-                (mDictionaryFacilitator.isConfidentAboutCurrentLanguageBeing(
-                        whitelistedWordInfo.mSourceDict.mLocale)
+                (mDictionaryFacilitator.isForLocale(whitelistedWordInfo.mSourceDict.mLocale)
                 || (!typedWordExistsInAnotherLanguage
                         && !hasPlausibleCandidateInAnyOtherLanguage(suggestionsContainer,
                                 consideredWord, whitelistedWordInfo)))) {
@@ -351,7 +350,7 @@ public final class Suggest {
                 wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
                 settingsValuesForSuggestion, SESSION_ID_GESTURE, inputStyle);
         // For transforming words that don't come from a dictionary, because it's our best bet
-        final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
+        final Locale locale = mDictionaryFacilitator.getLocale();
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 new ArrayList<>(suggestionResults);
         final int suggestionsCount = suggestionsContainer.size();
@@ -362,7 +361,7 @@ public final class Suggest {
                 final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
                 final Locale wordlocale = wordInfo.mSourceDict.mLocale;
                 final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
-                        wordInfo, null == wordlocale ? defaultLocale : wordlocale, isAllUpperCase,
+                        wordInfo, null == wordlocale ? locale : wordlocale, isAllUpperCase,
                         isFirstCharCapitalized, 0 /* trailingSingleQuotesCount */);
                 suggestionsContainer.set(i, transformedWordInfo);
             }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 35486ce95bd8aa4b3cab752eff98cefc62930bb0..f3840f74e137e73cbefc362cc100342c13529f6e 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -279,7 +279,6 @@ public final class InputLogic {
                     currentKeyboardScriptId, handler);
         }
 
-        mDictionaryFacilitator.switchMostProbableLanguage(suggestionInfo.mSourceDict.mLocale);
         final Event event = Event.createSuggestionPickedEvent(suggestionInfo);
         final InputTransaction inputTransaction = new InputTransaction(settingsValues,
                 event, SystemClock.uptimeMillis(), mSpaceState, keyboardShiftState);
@@ -2042,10 +2041,6 @@ public final class InputLogic {
             final boolean isBatchMode = mWordComposer.isBatchMode();
             commitChosenWord(settingsValues, stringToCommit,
                     LastComposedWord.COMMIT_TYPE_DECIDED_WORD, separator);
-            if (null != autoCorrectionOrNull) {
-                mDictionaryFacilitator.switchMostProbableLanguage(
-                        autoCorrectionOrNull.mSourceDict.mLocale);
-            }
             if (!typedWord.equals(stringToCommit)) {
                 // This will make the correction flash for a short while as a visual clue
                 // to the user that auto-correction happened. It has no other effect; in particular
diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtils.java b/java/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtils.java
index fa1583b7a00a8ae6212e56add5eac9c7df2d7cbd..a5a1ea921dc170a75de04e4678cb98def807e280 100644
--- a/java/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtils.java
@@ -33,7 +33,6 @@ public final class LanguageOnSpacebarUtils {
     public static final int FORMAT_TYPE_NONE = 0;
     public static final int FORMAT_TYPE_LANGUAGE_ONLY = 1;
     public static final int FORMAT_TYPE_FULL_LOCALE = 2;
-    public static final int FORMAT_TYPE_MULTIPLE = 3;
 
     private static List<InputMethodSubtype> sEnabledSubtypes = Collections.emptyList();
     private static boolean sIsSystemLanguageSameAsInputLanguage;
@@ -51,11 +50,11 @@ public final class LanguageOnSpacebarUtils {
         if (sEnabledSubtypes.size() < 2 && sIsSystemLanguageSameAsInputLanguage) {
             return FORMAT_TYPE_NONE;
         }
-        final Locale[] locales = subtype.getLocales();
-        if (1 < locales.length) {
-            return FORMAT_TYPE_MULTIPLE;
+        final Locale locale = subtype.getLocale();
+        if (locale == null) {
+            return FORMAT_TYPE_NONE;
         }
-        final String keyboardLanguage = locales[0].getLanguage();
+        final String keyboardLanguage = locale.getLanguage();
         final String keyboardLayout = subtype.getKeyboardLayoutSetName();
         int sameLanguageAndLayoutCount = 0;
         for (final InputMethodSubtype ims : sEnabledSubtypes) {
@@ -77,14 +76,7 @@ public final class LanguageOnSpacebarUtils {
 
     public static void onSubtypeChanged(@Nonnull final RichInputMethodSubtype subtype,
            final boolean implicitlyEnabledSubtype, @Nonnull final Locale systemLocale) {
-        final Locale[] newLocales = subtype.getLocales();
-        if (newLocales.length > 1) {
-            // In multi-locales mode, the system language is never the same as the input language
-            // because there is no single input language.
-            sIsSystemLanguageSameAsInputLanguage = false;
-            return;
-        }
-        final Locale newLocale = newLocales[0];
+        final Locale newLocale = subtype.getLocale();
         if (systemLocale.equals(newLocale)) {
             sIsSystemLanguageSameAsInputLanguage = true;
             return;
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index 7eccd4d5f025baa5b0fe3117f729c44ea42721e8..9da1e94703bc6f353539bc084ed1a36fb00d1e25 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -1102,25 +1102,4 @@ public class BinaryDictionaryTests extends AndroidTestCase {
         assertEquals(bigramProbability,
                 binaryDictionary.getNgramProbability(beginningOfSentenceContext, "bbb"));
     }
-
-    public void testGetMaxFrequencyOfExactMatches() {
-        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
-            testGetMaxFrequencyOfExactMatches(formatVersion);
-        }
-    }
-
-    private void testGetMaxFrequencyOfExactMatches(final int formatVersion) {
-        final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion);
-        addUnigramWord(binaryDictionary, "abc", 10);
-        addUnigramWord(binaryDictionary, "aBc", 15);
-        assertEquals(15, binaryDictionary.getMaxFrequencyOfExactMatches("abc"));
-        addUnigramWord(binaryDictionary, "ab'c", 20);
-        assertEquals(20, binaryDictionary.getMaxFrequencyOfExactMatches("abc"));
-        addUnigramWord(binaryDictionary, "a-b-c", 25);
-        assertEquals(25, binaryDictionary.getMaxFrequencyOfExactMatches("abc"));
-        addUnigramWord(binaryDictionary, "ab-'-'-'-c", 30);
-        assertEquals(30, binaryDictionary.getMaxFrequencyOfExactMatches("abc"));
-        addUnigramWord(binaryDictionary, "ab c", 255);
-        assertEquals(30, binaryDictionary.getMaxFrequencyOfExactMatches("abc"));
-    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java b/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java
index 4f924abc79ef38fcada292de6cef3ce9675c411d..6b0bbc27975e4b6bf70c0409e1bcfbcfd5109b86 100644
--- a/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java
+++ b/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java
@@ -29,28 +29,14 @@ public class DictionaryFacilitatorLruCacheTests extends AndroidTestCase {
 
         final DictionaryFacilitator dictionaryFacilitatorEnUs = cache.get(Locale.US);
         assertNotNull(dictionaryFacilitatorEnUs);
-        assertTrue(dictionaryFacilitatorEnUs.isForLocales(new Locale[] { Locale.US }));
+        assertTrue(dictionaryFacilitatorEnUs.isForLocale(Locale.US));
 
         final DictionaryFacilitator dictionaryFacilitatorFr = cache.get(Locale.FRENCH);
         assertNotNull(dictionaryFacilitatorEnUs);
-        assertTrue(dictionaryFacilitatorFr.isForLocales(new Locale[] { Locale.FRENCH }));
+        assertTrue(dictionaryFacilitatorFr.isForLocale(Locale.FRENCH));
 
         final DictionaryFacilitator dictionaryFacilitatorDe = cache.get(Locale.GERMANY);
         assertNotNull(dictionaryFacilitatorDe);
-        assertTrue(dictionaryFacilitatorDe.isForLocales(new Locale[] { Locale.GERMANY }));
-    }
-
-    public void testSetUseContactsDictionary() {
-        final DictionaryFacilitatorLruCache cache =
-                new DictionaryFacilitatorLruCache(getContext(), "");
-
-        assertNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
-        cache.setUseContactsDictionary(true /* useContactsDictionary */);
-        assertNotNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
-        assertNotNull(cache.get(Locale.FRENCH).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
-        assertNotNull(cache.get(Locale.GERMANY).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
-        cache.setUseContactsDictionary(false /* useContactsDictionary */);
-        assertNull(cache.get(Locale.GERMANY).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
-        assertNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
+        assertTrue(dictionaryFacilitatorDe.isForLocale(Locale.GERMANY));
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
deleted file mode 100644
index 6c6f6287225969812fe796eb6ca7d38d6ea565a8..0000000000000000000000000000000000000000
--- a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.ProbabilityInfo;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-
-import java.util.HashMap;
-
-/**
- * Unit test for FusionDictionary
- */
-@SmallTest
-public class FusionDictionaryTests extends AndroidTestCase {
-    public void testFindWordInTree() {
-        FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
-                new DictionaryOptions(new HashMap<String,String>()));
-
-        dict.add("abc", new ProbabilityInfo(10), false /* isNotAWord */,
-                false /* isPossiblyOffensive */);
-        assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa"));
-        assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "abc"));
-
-        dict.add("aa", new ProbabilityInfo(10), false /* isNotAWord */,
-                false /* isPossiblyOffensive */);
-        assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa"));
-        assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aa"));
-
-        dict.add("babcd", new ProbabilityInfo(10), false /* isNotAWord */,
-                false /* isPossiblyOffensive */);
-        dict.add("bacde", new ProbabilityInfo(10), false /* isNotAWord */,
-                false /* isPossiblyOffensive */);
-        assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "ba"));
-        assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "babcd"));
-        assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "bacde"));
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java b/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java
index d59890a96846e0660258755112dde5847af4832b..af94be66452d1a5755e274173b540aaec07c5229 100644
--- a/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java
+++ b/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java
@@ -164,17 +164,12 @@ public class RichInputMethodSubtypeTests extends AndroidTestCase {
             final String subtypeName = SubtypeLocaleUtils
                     .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
             final String spacebarText = subtype.getFullDisplayName();
-            final Locale[] locales = subtype.getLocales();
-            if (1 == locales.length) {
-                final String languageName = SubtypeLocaleUtils
-                        .getSubtypeLocaleDisplayName(locales[0].toString());
-                if (subtype.isNoLanguage()) {
-                    assertFalse(subtypeName, spacebarText.contains(languageName));
-                } else {
-                    assertTrue(subtypeName, spacebarText.contains(languageName));
-                }
+            final String languageName = SubtypeLocaleUtils
+                    .getSubtypeLocaleDisplayName(subtype.getLocale().toString());
+            if (subtype.isNoLanguage()) {
+                assertFalse(subtypeName, spacebarText.contains(languageName));
             } else {
-                // TODO: test multi-lingual subtype spacebar display
+                assertTrue(subtypeName, spacebarText.contains(languageName));
             }
         }
     }
@@ -183,12 +178,7 @@ public class RichInputMethodSubtypeTests extends AndroidTestCase {
         for (final RichInputMethodSubtype subtype : mSubtypesList) {
             final String subtypeName = SubtypeLocaleUtils
                     .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
-            final Locale[] locales = subtype.getLocales();
-            if (locales.length > 1) {
-                // TODO: test multi-lingual subtype spacebar display
-                continue;
-            }
-            final Locale locale = locales[0];
+            final Locale locale = subtype.getLocale();
             final Locale displayLocale = SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale(
                     locale.toString());
             if (Locale.ROOT.equals(displayLocale)) {
diff --git a/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java
index 7f7f493b17fb20f9bb235e9a518579735b363667..e4b6a668cd812a88cca1e037fa0a9add16b6d90b 100644
--- a/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java
@@ -94,7 +94,7 @@ public class LanguageOnSpacebarUtilsTests extends AndroidTestCase {
             final boolean implicitlyEnabledSubtype, final Locale systemLocale,
             final int expectedFormat) {
         LanguageOnSpacebarUtils.onSubtypeChanged(subtype, implicitlyEnabledSubtype, systemLocale);
-        assertEquals(subtype.getLocales()[0] + " implicitly=" + implicitlyEnabledSubtype
+        assertEquals(subtype.getLocale() + " implicitly=" + implicitlyEnabledSubtype
                 + " in " + systemLocale, expectedFormat,
                 LanguageOnSpacebarUtils.getLanguageOnSpacebarFormatType(subtype));
     }
diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
index b5232a3dab95b678d165260c8948ff17636e44c4..2297cacf8ca2ae292179fd73212c87e59ad19309 100644
--- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
@@ -147,19 +147,14 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
         for (final RichInputMethodSubtype subtype : mSubtypesList) {
             final String subtypeName = SubtypeLocaleUtils
                     .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
-            final Locale[] locales = subtype.getLocales();
-            if (1 == locales.length) {
-                if (subtype.isNoLanguage()) {
-                    final String layoutName = SubtypeLocaleUtils
-                            .getKeyboardLayoutSetDisplayName(subtype.getRawSubtype());
-                    assertTrue(subtypeName, subtypeName.contains(layoutName));
-                } else {
-                    final String languageName = SubtypeLocaleUtils
-                            .getSubtypeLocaleDisplayNameInSystemLocale(locales[0].toString());
-                    assertTrue(subtypeName, subtypeName.contains(languageName));
-                }
+            if (subtype.isNoLanguage()) {
+                final String layoutName = SubtypeLocaleUtils
+                        .getKeyboardLayoutSetDisplayName(subtype.getRawSubtype());
+                assertTrue(subtypeName, subtypeName.contains(layoutName));
             } else {
-                // TODO: test multi-lingual subtype spacebar display
+                final String languageName = SubtypeLocaleUtils
+                        .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale().toString());
+                assertTrue(subtypeName, subtypeName.contains(languageName));
             }
         }
     }