diff --git a/java-overridable/src/com/android/inputmethod/latin/DictionaryFacilitatorProvider.java b/java-overridable/src/com/android/inputmethod/latin/DictionaryFacilitatorProvider.java
new file mode 100644
index 0000000..5489de1
--- /dev/null
+++ b/java-overridable/src/com/android/inputmethod/latin/DictionaryFacilitatorProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 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.content.Context;
+
+/**
+ * Factory for instantiating DictionaryFacilitator objects.
+ */
+public class DictionaryFacilitatorProvider {
+    public static DictionaryFacilitator newDictionaryFacilitator() {
+        return new DictionaryFacilitatorImpl();
+    }
+
+    public static DictionaryFacilitator newDictionaryFacilitator(final Context context) {
+        return new DictionaryFacilitatorImpl(context);
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index b8893a5..a0a1d93 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -17,272 +17,58 @@
 package com.android.inputmethod.latin;
 
 import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
 import android.view.inputmethod.InputMethodSubtype;
+import android.util.Pair;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
-import com.android.inputmethod.latin.NgramContext.WordInfo;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.common.Constants;
-import com.android.inputmethod.latin.personalization.ContextualDictionary;
 import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
-import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
 import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
-import com.android.inputmethod.latin.utils.DistracterFilter;
-import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions;
-import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary;
-import com.android.inputmethod.latin.utils.ExecutorUtils;
 import com.android.inputmethod.latin.utils.SuggestionResults;
 
 import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Locale;
+import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 /**
- * Facilitates interaction with different kinds of dictionaries. Provides APIs
- * to instantiate and select the correct dictionaries (based on language or account),
- * update entries and fetch suggestions.
- *
- * Currently AndroidSpellCheckerService and LatinIME both use DictionaryFacilitator as
- * a client for interacting with dictionaries.
+ * Interface that facilitates interaction with different kinds of dictionaries. Provides APIs to
+ * instantiate and select the correct dictionaries (based on language or account), update entries
+ * and fetch suggestions. Currently AndroidSpellCheckerService and LatinIME both use
+ * DictionaryFacilitator as a client for interacting with dictionaries.
  */
-public class DictionaryFacilitator {
-    // TODO: Consolidate dictionaries in native code.
-    public static final String TAG = DictionaryFacilitator.class.getSimpleName();
-
-    // 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 boolean mIsUserDictEnabled = false;
-    private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
-    // To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
-    private final Object mLock = new Object();
-    private final DistracterFilter mDistracterFilter;
-    private final PersonalizationHelperForDictionaryFacilitator mPersonalizationHelper;
-
-    private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS =
-            new String[] {
-                Dictionary.TYPE_MAIN,
-                Dictionary.TYPE_USER_HISTORY,
-                Dictionary.TYPE_PERSONALIZATION,
-                Dictionary.TYPE_USER,
-                Dictionary.TYPE_CONTACTS,
-                Dictionary.TYPE_CONTEXTUAL
-            };
-
-    public static final Map<String, Class<? extends ExpandableBinaryDictionary>>
-            DICT_TYPE_TO_CLASS = new HashMap<>();
-
-    static {
-        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class);
-        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_PERSONALIZATION, PersonalizationDictionary.class);
-        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER, UserBinaryDictionary.class);
-        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTACTS, ContactsBinaryDictionary.class);
-        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTEXTUAL, ContextualDictionary.class);
-    }
-
-    private static final String DICT_FACTORY_METHOD_NAME = "getDictionary";
-    private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
-            new Class[] { Context.class, Locale.class, File.class, String.class, String.class };
-
-    private static final String[] SUB_DICT_TYPES =
-            Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS, 1 /* start */,
-                    DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length);
-
+public interface DictionaryFacilitator {
     /**
      * 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;
-    }
+    boolean isForLocales(final Locale[] locales);
 
     /**
      * Returns whether this facilitator is exactly for this account.
      *
      * @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;
+    boolean isForAccount(@Nullable final String account);
+
+    interface DictionaryInitializationListener {
+        void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
     }
 
-    /**
-     * A group of dictionaries that work together for a single language.
-     */
-    private static class DictionaryGroup {
-        // TODO: Add null analysis annotations.
-        // TODO: Run evaluation to determine a reasonable value for these constants. The current
-        // values are ad-hoc and chosen without any particular care or methodology.
-        public static final float WEIGHT_FOR_MOST_PROBABLE_LANGUAGE = 1.0f;
-        public static final float WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.95f;
-        public static final float WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.6f;
-
-        /**
-         * The locale associated with the dictionary group.
-         */
-        @Nullable public final Locale mLocale;
-
-        /**
-         * The user account associated with the dictionary group.
-         */
-        @Nullable public final String mAccount;
-
-        @Nullable private Dictionary mMainDict;
-        // Confidence that the most probable language is actually the language the user is
-        // typing in. For now, this is simply the number of times a word from this language
-        // has been committed in a row.
-        private int mConfidence = 0;
-
-        public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
-        public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
-        public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
-                new ConcurrentHashMap<>();
-
-        public DictionaryGroup() {
-            this(null /* locale */, null /* mainDict */, null /* account */,
-                    Collections.<String, ExpandableBinaryDictionary>emptyMap() /* subDicts */);
-        }
-
-        public DictionaryGroup(@Nullable final Locale locale,
-                @Nullable final Dictionary mainDict,
-                @Nullable final String account,
-                final Map<String, ExpandableBinaryDictionary> subDicts) {
-            mLocale = locale;
-            mAccount = account;
-            // The main dictionary can be asynchronously loaded.
-            setMainDict(mainDict);
-            for (final Map.Entry<String, ExpandableBinaryDictionary> entry : subDicts.entrySet()) {
-                setSubDict(entry.getKey(), entry.getValue());
-            }
-        }
-
-        private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) {
-            if (dict != null) {
-                mSubDictMap.put(dictType, dict);
-            }
-        }
-
-        public void setMainDict(final Dictionary mainDict) {
-            // Close old dictionary if exists. Main dictionary can be assigned multiple times.
-            final Dictionary oldDict = mMainDict;
-            mMainDict = mainDict;
-            if (oldDict != null && mainDict != oldDict) {
-                oldDict.close();
-            }
-        }
-
-        public Dictionary getDict(final String dictType) {
-            if (Dictionary.TYPE_MAIN.equals(dictType)) {
-                return mMainDict;
-            }
-            return getSubDict(dictType);
-        }
-
-        public ExpandableBinaryDictionary getSubDict(final String dictType) {
-            return mSubDictMap.get(dictType);
-        }
-
-        public boolean hasDict(final String dictType, @Nullable final String account) {
-            if (Dictionary.TYPE_MAIN.equals(dictType)) {
-                return mMainDict != null;
-            }
-            if (Dictionary.TYPE_USER_HISTORY.equals(dictType) &&
-                    !TextUtils.equals(account, mAccount)) {
-                // If the dictionary type is user history, & if the account doesn't match,
-                // return immediately. If the account matches, continue looking it up in the
-                // sub dictionary map.
-                return false;
-            }
-            return mSubDictMap.containsKey(dictType);
-        }
-
-        public void closeDict(final String dictType) {
-            final Dictionary dict;
-            if (Dictionary.TYPE_MAIN.equals(dictType)) {
-                dict = mMainDict;
-            } else {
-                dict = mSubDictMap.remove(dictType);
-            }
-            if (dict != null) {
-                dict.close();
-            }
-        }
-    }
-
-    public interface DictionaryInitializationListener {
-        public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
-    }
-
-    public DictionaryFacilitator() {
-        mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER;
-        mPersonalizationHelper = null;
-    }
-
-    public DictionaryFacilitator(final Context context) {
-        mDistracterFilter = new DistracterFilterCheckingExactMatchesAndSuggestions(context);
-        mPersonalizationHelper =
-                new PersonalizationHelperForDictionaryFacilitator(context, mDistracterFilter);
-    }
-
-    public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
-        mDistracterFilter.updateEnabledSubtypes(enabledSubtypes);
-        mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes);
-    }
+    void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes);
 
     // TODO: remove this, it's confusing with seamless multiple language switching
-    public void setIsMonolingualUser(final boolean isMonolingualUser) {
-        mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser);
-    }
+    void setIsMonolingualUser(final boolean isMonolingualUser);
 
-    public boolean isActive() {
-        return null != mDictionaryGroups[0].mLocale;
-    }
+    boolean isActive();
 
     /**
      * Returns the most probable locale among all currently active locales. BE CAREFUL using this.
@@ -292,660 +78,96 @@
      * string.
      * @return the most probable locale
      */
-    public Locale getMostProbableLocale() {
-        return getDictionaryGroupForMostProbableLanguage().mLocale;
-    }
+    Locale getMostProbableLocale();
 
-    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;
-    }
+    Locale[] getLocales();
 
-    private DictionaryGroup getDictionaryGroupForMostProbableLanguage() {
-        return mMostProbableDictionaryGroup;
-    }
+    void switchMostProbableLanguage(@Nullable final Locale locale);
 
-    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;
-        }
-    }
+    boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale);
 
-    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;
-    }
-
-    @Nullable
-    private static ExpandableBinaryDictionary getSubDict(final String dictType,
-            final Context context, final Locale locale, final File dictFile,
-            final String dictNamePrefix, @Nullable final String account) {
-        final Class<? extends ExpandableBinaryDictionary> dictClass =
-                DICT_TYPE_TO_CLASS.get(dictType);
-        if (dictClass == null) {
-            return null;
-        }
-        try {
-            final Method factoryMethod = dictClass.getMethod(DICT_FACTORY_METHOD_NAME,
-                    DICT_FACTORY_METHOD_ARG_TYPES);
-            final Object dict = factoryMethod.invoke(null /* obj */,
-                    new Object[] { context, locale, dictFile, dictNamePrefix, account });
-            return (ExpandableBinaryDictionary) dict;
-        } catch (final NoSuchMethodException | SecurityException | IllegalAccessException
-                | IllegalArgumentException | InvocationTargetException e) {
-            Log.e(TAG, "Cannot create dictionary: " + dictType, e);
-            return null;
-        }
-    }
-
-    public void resetDictionaries(final Context context, final Locale[] newLocales,
+    void resetDictionaries(final Context context, final Locale[] newLocales,
             final boolean useContactsDict, final boolean usePersonalizedDicts,
             final boolean forceReloadMainDictionary,
             @Nullable final String account,
-            final DictionaryInitializationListener listener) {
-        resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict,
-                usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */,
-                account);
-    }
+            final DictionaryInitializationListener listener);
 
-    @Nullable
-    static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
-            final Locale locale) {
-        for (DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            if (locale.equals(dictionaryGroup.mLocale)) {
-                return dictionaryGroup;
-            }
-        }
-        return null;
-    }
-
-    public void resetDictionariesWithDictNamePrefix(final Context context,
+    void resetDictionariesWithDictNamePrefix(final Context context,
             final Locale[] newLocales,
             final boolean useContactsDict,
             final boolean usePersonalizedDicts,
             final boolean forceReloadMainDictionary,
             @Nullable final DictionaryInitializationListener listener,
             final String dictNamePrefix,
-            @Nullable final String account) {
-        final HashMap<Locale, ArrayList<String>> existingDictionariesToCleanup = new HashMap<>();
-        // TODO: Make subDictTypesToUse configurable by resource or a static final list.
-        final HashSet<String> subDictTypesToUse = new HashSet<>();
-        subDictTypesToUse.add(Dictionary.TYPE_USER);
-        if (useContactsDict) {
-            subDictTypesToUse.add(Dictionary.TYPE_CONTACTS);
-        }
-        if (usePersonalizedDicts) {
-            subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY);
-            subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION);
-            subDictTypesToUse.add(Dictionary.TYPE_CONTEXTUAL);
-        }
-
-        // 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;
-            }
-            for (final String dictType : SUB_DICT_TYPES) {
-                if (currentDictionaryGroupForLocale.hasDict(dictType, account)) {
-                    dictTypeForLocale.add(dictType);
-                }
-            }
-            if (currentDictionaryGroupForLocale.hasDict(Dictionary.TYPE_MAIN, account)) {
-                dictTypeForLocale.add(Dictionary.TYPE_MAIN);
-            }
-        }
-
-        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 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);
-            }
-            newDictionaryGroups[i] = new DictionaryGroup(newLocale, mainDict, account, subDicts);
-        }
-
-        // Replace Dictionaries.
-        final DictionaryGroup[] oldDictionaryGroups;
-        synchronized (mLock) {
-            oldDictionaryGroups = mDictionaryGroups;
-            mDictionaryGroups = newDictionaryGroups;
-            mMostProbableDictionaryGroup = newDictionaryGroups[0];
-            mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
-            if (hasAtLeastOneUninitializedMainDictionary()) {
-                asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
-            }
-        }
-        if (listener != null) {
-            listener.onUpdateMainDictionaryAvailability(hasAtLeastOneInitializedMainDictionary());
-        }
-
-        // Clean up old dictionaries.
-        for (final Locale localeToCleanUp : existingDictionariesToCleanup.keySet()) {
-            final ArrayList<String> dictTypesToCleanUp =
-                    existingDictionariesToCleanup.get(localeToCleanUp);
-            final DictionaryGroup dictionarySetToCleanup =
-                    findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
-            for (final String dictType : dictTypesToCleanUp) {
-                dictionarySetToCleanup.closeDict(dictType);
-            }
-        }
-    }
-
-    private void asyncReloadUninitializedMainDictionaries(final Context context,
-            final Locale[] locales, final DictionaryInitializationListener listener) {
-        final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
-        mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
-        ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
-            @Override
-            public void run() {
-                doReloadUninitializedMainDictionaries(
-                        context, locales, listener, latchForWaitingLoadingMainDictionary);
-            }
-        });
-    }
-
-    void doReloadUninitializedMainDictionaries(final Context context, final Locale[] locales,
-            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();
-                }
-            }
-        }
-        if (listener != null) {
-            listener.onUpdateMainDictionaryAvailability(
-                    hasAtLeastOneInitializedMainDictionary());
-        }
-        latchForWaitingLoadingMainDictionary.countDown();
-    }
+            @Nullable final String account);
 
     @UsedForTesting
-    public void resetDictionariesForTesting(final Context context, final Locale[] locales,
+    void resetDictionariesForTesting(final Context context, final Locale[] locales,
             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<>();
+            @Nullable final String account);
 
-        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);
-                }
-            }
-            dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, account, subDicts);
-        }
-        mDictionaryGroups = dictionaryGroups;
-        mMostProbableDictionaryGroup = dictionaryGroups[0];
-    }
-
-    public void closeDictionaries() {
-        final DictionaryGroup[] dictionaryGroups;
-        synchronized (mLock) {
-            dictionaryGroups = mDictionaryGroups;
-            mMostProbableDictionaryGroup = new DictionaryGroup();
-            mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
-        }
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
-                dictionaryGroup.closeDict(dictType);
-            }
-        }
-        mDistracterFilter.close();
-        if (mPersonalizationHelper != null) {
-            mPersonalizationHelper.close();
-        }
-    }
+    void closeDictionaries();
 
     @UsedForTesting
-    public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
-        return mMostProbableDictionaryGroup.getSubDict(dictName);
-    }
+    ExpandableBinaryDictionary getSubDictForTesting(final String dictName);
 
-    // The main dictionaries are loaded asynchronously.  Don't cache the return value
+    // 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;
-            }
-        }
-        return false;
-    }
+    boolean hasAtLeastOneInitializedMainDictionary();
 
-    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;
-            }
-        }
-        return false;
-    }
+    boolean hasAtLeastOneUninitializedMainDictionary();
 
-    public boolean hasPersonalizationDictionary() {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            if (dictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION, null /* account */)) {
-                return true;
-            }
-        }
-        return false;
-    }
+    boolean hasPersonalizationDictionary();
 
-    public void flushPersonalizationDictionary() {
-        final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion =
-                new HashSet<>();
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            final ExpandableBinaryDictionary personalizationDictUsedForSuggestion =
-                    dictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION);
-            personalizationDictsUsedForSuggestion.add(personalizationDictUsedForSuggestion);
-        }
-        mPersonalizationHelper.flushPersonalizationDictionariesToUpdate(
-                personalizationDictsUsedForSuggestion);
-        mDistracterFilter.close();
-    }
+    void flushPersonalizationDictionary();
 
-    public void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
-            throws InterruptedException {
-        mLatchForWaitingLoadingMainDictionaries.await(timeout, unit);
-    }
+    void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
+            throws InterruptedException;
 
     @UsedForTesting
-    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();
-            }
-        }
-    }
+    void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
+            throws InterruptedException;
 
-    public boolean isUserDictionaryEnabled() {
-        return mIsUserDictEnabled;
-    }
+    boolean isUserDictionaryEnabled();
 
-    public void addWordToUserDictionary(final Context context, final String word) {
-        final Locale locale = getMostProbableLocale();
-        if (locale == null) {
-            return;
-        }
-        // TODO: add a toast telling what language this is being added to?
-        UserBinaryDictionary.addWordToUserDictionary(context, locale, word);
-    }
+    void addWordToUserDictionary(final Context context, final String word);
 
-    public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
+    void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
             @Nonnull final NgramContext ngramContext, final int 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, timeStampInSeconds, blockPotentiallyOffensive);
-            ngramContextForCurrentWord =
-                    ngramContextForCurrentWord.getNextNgramContext(new WordInfo(currentWord));
-        }
-    }
+            final boolean blockPotentiallyOffensive);
 
-    private void addWordToUserHistory(final DictionaryGroup dictionaryGroup,
-            final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized,
-            final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
-        final ExpandableBinaryDictionary userHistoryDictionary =
-                dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY);
-        if (userHistoryDictionary == null
-                || !isConfidentAboutCurrentLanguageBeing(userHistoryDictionary.mLocale)) {
-            return;
-        }
-        final int maxFreq = getFrequency(word);
-        if (maxFreq == 0 && blockPotentiallyOffensive) {
-            return;
-        }
-        final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
-        final String secondWord;
-        if (wasAutoCapitalized) {
-            if (isValidWord(word, false /* ignoreCase */)
-                    && !isValidWord(lowerCasedWord, false /* ignoreCase */)) {
-                // If the word was auto-capitalized and exists only as a capitalized word in the
-                // dictionary, then we must not downcase it before registering it. For example,
-                // the name of the contacts in start-of-sentence position would come here with the
-                // wasAutoCapitalized flag: if we downcase it, we'd register a lower-case version
-                // of that contact's name which would end up popping in suggestions.
-                secondWord = word;
-            } else {
-                // If however the word is not in the dictionary, or exists as a lower-case word
-                // only, then we consider that was a lower-case word that had been auto-capitalized.
-                secondWord = lowerCasedWord;
-            }
-        } else {
-            // HACK: We'd like to avoid adding the capitalized form of common words to the User
-            // History dictionary in order to avoid suggesting them until the dictionary
-            // consolidation is done.
-            // TODO: Remove this hack when ready.
-            final int lowerCaseFreqInMainDict = dictionaryGroup.hasDict(Dictionary.TYPE_MAIN,
-                    null /* account */) ?
-                    dictionaryGroup.getDict(Dictionary.TYPE_MAIN).getFrequency(lowerCasedWord) :
-                            Dictionary.NOT_A_PROBABILITY;
-            if (maxFreq < lowerCaseFreqInMainDict
-                    && lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) {
-                // Use lower cased word as the word can be a distracter of the popular word.
-                secondWord = lowerCasedWord;
-            } else {
-                secondWord = word;
-            }
-        }
-        // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
-        // We don't add words with 0-frequency (assuming they would be profanity etc.).
-        final boolean isValid = maxFreq > 0;
-        UserHistoryDictionary.addToDictionary(userHistoryDictionary, ngramContext, secondWord,
-                isValid, timeStampInSeconds,
-                new DistracterFilterCheckingIsInDictionary(
-                        mDistracterFilter, userHistoryDictionary));
-    }
-
-    private void removeWord(final String dictName, final String word) {
-        final ExpandableBinaryDictionary dictionary =
-                getDictionaryGroupForMostProbableLanguage().getSubDict(dictName);
-        if (dictionary != null) {
-            dictionary.removeUnigramEntryDynamically(word);
-        }
-    }
-
-    public void removeWordFromPersonalizedDicts(final String word) {
-        removeWord(Dictionary.TYPE_USER_HISTORY, word);
-        removeWord(Dictionary.TYPE_PERSONALIZATION, word);
-        removeWord(Dictionary.TYPE_CONTEXTUAL, word);
-    }
+    void removeWordFromPersonalizedDicts(final String word);
 
     // TODO: Revise the way to fusion suggestion results.
-    public SuggestionResults getSuggestionResults(final WordComposer composer,
+    SuggestionResults getSuggestionResults(final WordComposer composer,
             final NgramContext ngramContext, final long proximityInfoHandle,
-            final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        final SuggestionResults suggestionResults = new SuggestionResults(
-                SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext());
-        final float[] weightOfLangModelVsSpatialModel =
-                new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
-                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
-                if (null == dictionary) continue;
-                final float weightForLocale = composer.isBatchMode()
-                        ? dictionaryGroup.mWeightForGesturingInLocale
-                        : dictionaryGroup.mWeightForTypingInLocale;
-                final ArrayList<SuggestedWordInfo> dictionarySuggestions =
-                        dictionary.getSuggestions(composer.getComposedDataSnapshot(), ngramContext,
-                                proximityInfoHandle, settingsValuesForSuggestion, sessionId,
-                                weightForLocale, weightOfLangModelVsSpatialModel);
-                if (null == dictionarySuggestions) continue;
-                suggestionResults.addAll(dictionarySuggestions);
-                if (null != suggestionResults.mRawSuggestions) {
-                    suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
-                }
-            }
-        }
-        return suggestionResults;
-    }
+            final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId);
 
-    public boolean isValidWord(final String word, final boolean ignoreCase) {
-        if (TextUtils.isEmpty(word)) {
-            return false;
-        }
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            if (dictionaryGroup.mLocale == null) {
-                continue;
-            }
-            final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
-                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)
-                        || (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
+    boolean isValidWord(final String word, final boolean ignoreCase);
 
-    private int getFrequencyInternal(final String word,
-            final boolean isGettingMaxFrequencyOfExactMatches) {
-        if (TextUtils.isEmpty(word)) {
-            return Dictionary.NOT_A_PROBABILITY;
-        }
-        int maxFreq = Dictionary.NOT_A_PROBABILITY;
-        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
-        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
-                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
-                if (dictionary == null) continue;
-                final int tempFreq;
-                if (isGettingMaxFrequencyOfExactMatches) {
-                    tempFreq = dictionary.getMaxFrequencyOfExactMatches(word);
-                } else {
-                    tempFreq = dictionary.getFrequency(word);
-                }
-                if (tempFreq >= maxFreq) {
-                    maxFreq = tempFreq;
-                }
-            }
-        }
-        return maxFreq;
-    }
+    int getFrequency(final String word);
 
-    public int getFrequency(final String word) {
-        return getFrequencyInternal(word, false /* isGettingMaxFrequencyOfExactMatches */);
-    }
+    int getMaxFrequencyOfExactMatches(final String word);
 
-    public int getMaxFrequencyOfExactMatches(final String word) {
-        return getFrequencyInternal(word, true /* isGettingMaxFrequencyOfExactMatches */);
-    }
-
-    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();
-            }
-        }
-    }
-
-    public void clearUserHistoryDictionary() {
-        clearSubDictionary(Dictionary.TYPE_USER_HISTORY);
-    }
+    void clearUserHistoryDictionary();
 
     // This method gets called only when the IME receives a notification to remove the
     // personalization dictionary.
-    public void clearPersonalizationDictionary() {
-        clearSubDictionary(Dictionary.TYPE_PERSONALIZATION);
-        mPersonalizationHelper.clearDictionariesToUpdate();
-    }
+    void clearPersonalizationDictionary();
 
-    public void clearContextualDictionary() {
-        clearSubDictionary(Dictionary.TYPE_CONTEXTUAL);
-    }
+    void clearContextualDictionary();
 
-    public void addEntriesToPersonalizationDictionary(
+    void addEntriesToPersonalizationDictionary(
             final PersonalizationDataChunk personalizationDataChunk,
             final SpacingAndPunctuations spacingAndPunctuations,
-            final UpdateEntriesForInputEventsCallback callback) {
-        mPersonalizationHelper.updateEntriesOfPersonalizationDictionaries(
-                getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations,
-                callback);
-    }
+            final UpdateEntriesForInputEventsCallback callback);
 
     @UsedForTesting
-    public void addPhraseToContextualDictionary(final String[] phrase, final int probability,
-            final int bigramProbabilityForWords, final int bigramProbabilityForPhrases) {
-        // TODO: we're inserting the phrase into the dictionary for the active language. Rethink
-        // this a bit from a theoretical point of view.
-        final ExpandableBinaryDictionary contextualDict =
-                getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
-        if (contextualDict == null) {
-            return;
-        }
-        NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE;
-        for (int i = 0; i < phrase.length; i++) {
-            final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length);
-            final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase);
-            contextualDict.addUnigramEntryWithCheckingDistracter(
-                    subPhraseStr, probability, null /* shortcutTarget */,
-                    Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
-                    false /* isNotAWord */, false /* isPossiblyOffensive */,
-                    BinaryDictionary.NOT_A_VALID_TIMESTAMP,
-                    DistracterFilter.EMPTY_DISTRACTER_FILTER);
-            contextualDict.addNgramEntry(ngramContext, subPhraseStr,
-                    bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+    void addPhraseToContextualDictionary(final String[] phrase, final int probability,
+            final int bigramProbabilityForWords, final int bigramProbabilityForPhrases);
 
-            if (i < phrase.length - 1) {
-                contextualDict.addUnigramEntryWithCheckingDistracter(
-                        phrase[i], probability, null /* shortcutTarget */,
-                        Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
-                        false /* isNotAWord */, false /* isPossiblyOffensive */,
-                        BinaryDictionary.NOT_A_VALID_TIMESTAMP,
-                        DistracterFilter.EMPTY_DISTRACTER_FILTER);
-                contextualDict.addNgramEntry(ngramContext, phrase[i],
-                        bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
-            }
-            ngramContext =
-                    ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i]));
-        }
-    }
+    void dumpDictionaryForDebug(final String dictName);
 
-    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();
-        }
-    }
-
-    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 : SUB_DICT_TYPES) {
-                final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictType);
-                if (dictionary == null) continue;
-                statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
-            }
-        }
-        return statsOfEnabledSubDicts;
-    }
+    ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts();
 }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
new file mode 100644
index 0000000..1675011
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -0,0 +1,947 @@
+/*
+ * Copyright (C) 2013 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.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
+import com.android.inputmethod.latin.NgramContext.WordInfo;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.personalization.ContextualDictionary;
+import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
+import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
+import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
+import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import com.android.inputmethod.latin.utils.DistracterFilter;
+import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions;
+import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
+import com.android.inputmethod.latin.utils.SuggestionResults;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Facilitates interaction with different kinds of dictionaries. Provides APIs
+ * to instantiate and select the correct dictionaries (based on language or account),
+ * update entries and fetch suggestions.
+ *
+ * Currently AndroidSpellCheckerService and LatinIME both use DictionaryFacilitator as
+ * a client for interacting with dictionaries.
+ */
+public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
+    // TODO: Consolidate dictionaries in native code.
+    public static final String TAG = DictionaryFacilitatorImpl.class.getSimpleName();
+
+    // 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 boolean mIsUserDictEnabled = false;
+    private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
+    // To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
+    private final Object mLock = new Object();
+    private final DistracterFilter mDistracterFilter;
+    private final PersonalizationHelperForDictionaryFacilitator mPersonalizationHelper;
+
+    private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS =
+            new String[] {
+                Dictionary.TYPE_MAIN,
+                Dictionary.TYPE_USER_HISTORY,
+                Dictionary.TYPE_PERSONALIZATION,
+                Dictionary.TYPE_USER,
+                Dictionary.TYPE_CONTACTS,
+                Dictionary.TYPE_CONTEXTUAL
+            };
+
+    public static final Map<String, Class<? extends ExpandableBinaryDictionary>>
+            DICT_TYPE_TO_CLASS = new HashMap<>();
+
+    static {
+        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class);
+        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_PERSONALIZATION, PersonalizationDictionary.class);
+        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER, UserBinaryDictionary.class);
+        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTACTS, ContactsBinaryDictionary.class);
+        DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTEXTUAL, ContextualDictionary.class);
+    }
+
+    private static final String DICT_FACTORY_METHOD_NAME = "getDictionary";
+    private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
+            new Class[] { Context.class, Locale.class, File.class, String.class, String.class };
+
+    private static final String[] SUB_DICT_TYPES =
+            Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS, 1 /* start */,
+                    DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length);
+
+    /**
+     * 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;
+    }
+
+    /**
+     * Returns whether this facilitator is exactly for this account.
+     *
+     * @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;
+    }
+
+    /**
+     * A group of dictionaries that work together for a single language.
+     */
+    private static class DictionaryGroup {
+        // TODO: Add null analysis annotations.
+        // TODO: Run evaluation to determine a reasonable value for these constants. The current
+        // values are ad-hoc and chosen without any particular care or methodology.
+        public static final float WEIGHT_FOR_MOST_PROBABLE_LANGUAGE = 1.0f;
+        public static final float WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.95f;
+        public static final float WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.6f;
+
+        /**
+         * The locale associated with the dictionary group.
+         */
+        @Nullable public final Locale mLocale;
+
+        /**
+         * The user account associated with the dictionary group.
+         */
+        @Nullable public final String mAccount;
+
+        @Nullable private Dictionary mMainDict;
+        // Confidence that the most probable language is actually the language the user is
+        // typing in. For now, this is simply the number of times a word from this language
+        // has been committed in a row.
+        private int mConfidence = 0;
+
+        public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+        public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+        public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
+                new ConcurrentHashMap<>();
+
+        public DictionaryGroup() {
+            this(null /* locale */, null /* mainDict */, null /* account */,
+                    Collections.<String, ExpandableBinaryDictionary>emptyMap() /* subDicts */);
+        }
+
+        public DictionaryGroup(@Nullable final Locale locale,
+                @Nullable final Dictionary mainDict,
+                @Nullable final String account,
+                final Map<String, ExpandableBinaryDictionary> subDicts) {
+            mLocale = locale;
+            mAccount = account;
+            // The main dictionary can be asynchronously loaded.
+            setMainDict(mainDict);
+            for (final Map.Entry<String, ExpandableBinaryDictionary> entry : subDicts.entrySet()) {
+                setSubDict(entry.getKey(), entry.getValue());
+            }
+        }
+
+        private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) {
+            if (dict != null) {
+                mSubDictMap.put(dictType, dict);
+            }
+        }
+
+        public void setMainDict(final Dictionary mainDict) {
+            // Close old dictionary if exists. Main dictionary can be assigned multiple times.
+            final Dictionary oldDict = mMainDict;
+            mMainDict = mainDict;
+            if (oldDict != null && mainDict != oldDict) {
+                oldDict.close();
+            }
+        }
+
+        public Dictionary getDict(final String dictType) {
+            if (Dictionary.TYPE_MAIN.equals(dictType)) {
+                return mMainDict;
+            }
+            return getSubDict(dictType);
+        }
+
+        public ExpandableBinaryDictionary getSubDict(final String dictType) {
+            return mSubDictMap.get(dictType);
+        }
+
+        public boolean hasDict(final String dictType, @Nullable final String account) {
+            if (Dictionary.TYPE_MAIN.equals(dictType)) {
+                return mMainDict != null;
+            }
+            if (Dictionary.TYPE_USER_HISTORY.equals(dictType) &&
+                    !TextUtils.equals(account, mAccount)) {
+                // If the dictionary type is user history, & if the account doesn't match,
+                // return immediately. If the account matches, continue looking it up in the
+                // sub dictionary map.
+                return false;
+            }
+            return mSubDictMap.containsKey(dictType);
+        }
+
+        public void closeDict(final String dictType) {
+            final Dictionary dict;
+            if (Dictionary.TYPE_MAIN.equals(dictType)) {
+                dict = mMainDict;
+            } else {
+                dict = mSubDictMap.remove(dictType);
+            }
+            if (dict != null) {
+                dict.close();
+            }
+        }
+    }
+
+    public DictionaryFacilitatorImpl() {
+        mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER;
+        mPersonalizationHelper = null;
+    }
+
+    public DictionaryFacilitatorImpl(final Context context) {
+        mDistracterFilter = new DistracterFilterCheckingExactMatchesAndSuggestions(context);
+        mPersonalizationHelper =
+                new PersonalizationHelperForDictionaryFacilitator(context, mDistracterFilter);
+    }
+
+    public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
+        mDistracterFilter.updateEnabledSubtypes(enabledSubtypes);
+        mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes);
+    }
+
+    // TODO: remove this, it's confusing with seamless multiple language switching
+    public void setIsMonolingualUser(final boolean isMonolingualUser) {
+        mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser);
+    }
+
+    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;
+    }
+
+    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;
+    }
+
+    @Nullable
+    private static ExpandableBinaryDictionary getSubDict(final String dictType,
+            final Context context, final Locale locale, final File dictFile,
+            final String dictNamePrefix, @Nullable final String account) {
+        final Class<? extends ExpandableBinaryDictionary> dictClass =
+                DICT_TYPE_TO_CLASS.get(dictType);
+        if (dictClass == null) {
+            return null;
+        }
+        try {
+            final Method factoryMethod = dictClass.getMethod(DICT_FACTORY_METHOD_NAME,
+                    DICT_FACTORY_METHOD_ARG_TYPES);
+            final Object dict = factoryMethod.invoke(null /* obj */,
+                    new Object[] { context, locale, dictFile, dictNamePrefix, account });
+            return (ExpandableBinaryDictionary) dict;
+        } catch (final NoSuchMethodException | SecurityException | IllegalAccessException
+                | IllegalArgumentException | InvocationTargetException e) {
+            Log.e(TAG, "Cannot create dictionary: " + dictType, e);
+            return null;
+        }
+    }
+
+    public void resetDictionaries(final Context context, final Locale[] newLocales,
+            final boolean useContactsDict, final boolean usePersonalizedDicts,
+            final boolean forceReloadMainDictionary,
+            @Nullable final String account,
+            final DictionaryInitializationListener listener) {
+        resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict,
+                usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */,
+                account);
+    }
+
+    @Nullable
+    static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
+            final Locale locale) {
+        for (DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            if (locale.equals(dictionaryGroup.mLocale)) {
+                return dictionaryGroup;
+            }
+        }
+        return null;
+    }
+
+    public void resetDictionariesWithDictNamePrefix(final Context context,
+            final Locale[] newLocales,
+            final boolean useContactsDict,
+            final boolean usePersonalizedDicts,
+            final boolean forceReloadMainDictionary,
+            @Nullable final DictionaryInitializationListener listener,
+            final String dictNamePrefix,
+            @Nullable final String account) {
+        final HashMap<Locale, ArrayList<String>> existingDictionariesToCleanup = new HashMap<>();
+        // TODO: Make subDictTypesToUse configurable by resource or a static final list.
+        final HashSet<String> subDictTypesToUse = new HashSet<>();
+        subDictTypesToUse.add(Dictionary.TYPE_USER);
+        if (useContactsDict) {
+            subDictTypesToUse.add(Dictionary.TYPE_CONTACTS);
+        }
+        if (usePersonalizedDicts) {
+            subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY);
+            subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION);
+            subDictTypesToUse.add(Dictionary.TYPE_CONTEXTUAL);
+        }
+
+        // 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;
+            }
+            for (final String dictType : SUB_DICT_TYPES) {
+                if (currentDictionaryGroupForLocale.hasDict(dictType, account)) {
+                    dictTypeForLocale.add(dictType);
+                }
+            }
+            if (currentDictionaryGroupForLocale.hasDict(Dictionary.TYPE_MAIN, account)) {
+                dictTypeForLocale.add(Dictionary.TYPE_MAIN);
+            }
+        }
+
+        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 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);
+            }
+            newDictionaryGroups[i] = new DictionaryGroup(newLocale, mainDict, account, subDicts);
+        }
+
+        // Replace Dictionaries.
+        final DictionaryGroup[] oldDictionaryGroups;
+        synchronized (mLock) {
+            oldDictionaryGroups = mDictionaryGroups;
+            mDictionaryGroups = newDictionaryGroups;
+            mMostProbableDictionaryGroup = newDictionaryGroups[0];
+            mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
+            if (hasAtLeastOneUninitializedMainDictionary()) {
+                asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
+            }
+        }
+        if (listener != null) {
+            listener.onUpdateMainDictionaryAvailability(hasAtLeastOneInitializedMainDictionary());
+        }
+
+        // Clean up old dictionaries.
+        for (final Locale localeToCleanUp : existingDictionariesToCleanup.keySet()) {
+            final ArrayList<String> dictTypesToCleanUp =
+                    existingDictionariesToCleanup.get(localeToCleanUp);
+            final DictionaryGroup dictionarySetToCleanup =
+                    findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
+            for (final String dictType : dictTypesToCleanUp) {
+                dictionarySetToCleanup.closeDict(dictType);
+            }
+        }
+    }
+
+    private void asyncReloadUninitializedMainDictionaries(final Context context,
+            final Locale[] locales, final DictionaryInitializationListener listener) {
+        final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
+        mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
+        ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
+            @Override
+            public void run() {
+                doReloadUninitializedMainDictionaries(
+                        context, locales, listener, latchForWaitingLoadingMainDictionary);
+            }
+        });
+    }
+
+    void doReloadUninitializedMainDictionaries(final Context context, final Locale[] locales,
+            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();
+                }
+            }
+        }
+        if (listener != null) {
+            listener.onUpdateMainDictionaryAvailability(
+                    hasAtLeastOneInitializedMainDictionary());
+        }
+        latchForWaitingLoadingMainDictionary.countDown();
+    }
+
+    @UsedForTesting
+    public void resetDictionariesForTesting(final Context context, final Locale[] locales,
+            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);
+                }
+            }
+            dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, account, subDicts);
+        }
+        mDictionaryGroups = dictionaryGroups;
+        mMostProbableDictionaryGroup = dictionaryGroups[0];
+    }
+
+    public void closeDictionaries() {
+        final DictionaryGroup[] dictionaryGroups;
+        synchronized (mLock) {
+            dictionaryGroups = mDictionaryGroups;
+            mMostProbableDictionaryGroup = new DictionaryGroup();
+            mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
+        }
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+                dictionaryGroup.closeDict(dictType);
+            }
+        }
+        mDistracterFilter.close();
+        if (mPersonalizationHelper != null) {
+            mPersonalizationHelper.close();
+        }
+    }
+
+    @UsedForTesting
+    public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
+        return mMostProbableDictionaryGroup.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;
+            }
+        }
+        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;
+            }
+        }
+        return false;
+    }
+
+    public boolean hasPersonalizationDictionary() {
+        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            if (dictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION, null /* account */)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void flushPersonalizationDictionary() {
+        final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion =
+                new HashSet<>();
+        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            final ExpandableBinaryDictionary personalizationDictUsedForSuggestion =
+                    dictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION);
+            personalizationDictsUsedForSuggestion.add(personalizationDictUsedForSuggestion);
+        }
+        mPersonalizationHelper.flushPersonalizationDictionariesToUpdate(
+                personalizationDictsUsedForSuggestion);
+        mDistracterFilter.close();
+    }
+
+    public void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        mLatchForWaitingLoadingMainDictionaries.await(timeout, unit);
+    }
+
+    @UsedForTesting
+    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();
+            }
+        }
+    }
+
+    public boolean isUserDictionaryEnabled() {
+        return mIsUserDictEnabled;
+    }
+
+    public void addWordToUserDictionary(final Context context, final String word) {
+        final Locale locale = getMostProbableLocale();
+        if (locale == null) {
+            return;
+        }
+        // TODO: add a toast telling what language this is being added to?
+        UserBinaryDictionary.addWordToUserDictionary(context, locale, word);
+    }
+
+    public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
+            @Nonnull final NgramContext ngramContext, final int 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, timeStampInSeconds, blockPotentiallyOffensive);
+            ngramContextForCurrentWord =
+                    ngramContextForCurrentWord.getNextNgramContext(new WordInfo(currentWord));
+        }
+    }
+
+    private void addWordToUserHistory(final DictionaryGroup dictionaryGroup,
+            final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized,
+            final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
+        final ExpandableBinaryDictionary userHistoryDictionary =
+                dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY);
+        if (userHistoryDictionary == null
+                || !isConfidentAboutCurrentLanguageBeing(userHistoryDictionary.mLocale)) {
+            return;
+        }
+        final int maxFreq = getFrequency(word);
+        if (maxFreq == 0 && blockPotentiallyOffensive) {
+            return;
+        }
+        final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
+        final String secondWord;
+        if (wasAutoCapitalized) {
+            if (isValidWord(word, false /* ignoreCase */)
+                    && !isValidWord(lowerCasedWord, false /* ignoreCase */)) {
+                // If the word was auto-capitalized and exists only as a capitalized word in the
+                // dictionary, then we must not downcase it before registering it. For example,
+                // the name of the contacts in start-of-sentence position would come here with the
+                // wasAutoCapitalized flag: if we downcase it, we'd register a lower-case version
+                // of that contact's name which would end up popping in suggestions.
+                secondWord = word;
+            } else {
+                // If however the word is not in the dictionary, or exists as a lower-case word
+                // only, then we consider that was a lower-case word that had been auto-capitalized.
+                secondWord = lowerCasedWord;
+            }
+        } else {
+            // HACK: We'd like to avoid adding the capitalized form of common words to the User
+            // History dictionary in order to avoid suggesting them until the dictionary
+            // consolidation is done.
+            // TODO: Remove this hack when ready.
+            final int lowerCaseFreqInMainDict = dictionaryGroup.hasDict(Dictionary.TYPE_MAIN,
+                    null /* account */) ?
+                    dictionaryGroup.getDict(Dictionary.TYPE_MAIN).getFrequency(lowerCasedWord) :
+                    Dictionary.NOT_A_PROBABILITY;
+            if (maxFreq < lowerCaseFreqInMainDict
+                    && lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) {
+                // Use lower cased word as the word can be a distracter of the popular word.
+                secondWord = lowerCasedWord;
+            } else {
+                secondWord = word;
+            }
+        }
+        // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
+        // We don't add words with 0-frequency (assuming they would be profanity etc.).
+        final boolean isValid = maxFreq > 0;
+        UserHistoryDictionary.addToDictionary(userHistoryDictionary, ngramContext, secondWord,
+                isValid, timeStampInSeconds,
+                new DistracterFilterCheckingIsInDictionary(
+                        mDistracterFilter, userHistoryDictionary));
+    }
+
+    private void removeWord(final String dictName, final String word) {
+        final ExpandableBinaryDictionary dictionary =
+                getDictionaryGroupForMostProbableLanguage().getSubDict(dictName);
+        if (dictionary != null) {
+            dictionary.removeUnigramEntryDynamically(word);
+        }
+    }
+
+    public void removeWordFromPersonalizedDicts(final String word) {
+        removeWord(Dictionary.TYPE_USER_HISTORY, word);
+        removeWord(Dictionary.TYPE_PERSONALIZATION, word);
+        removeWord(Dictionary.TYPE_CONTEXTUAL, word);
+    }
+
+    // TODO: Revise the way to fusion suggestion results.
+    public SuggestionResults getSuggestionResults(final WordComposer composer,
+            final NgramContext ngramContext, final long proximityInfoHandle,
+            final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
+        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+        final SuggestionResults suggestionResults = new SuggestionResults(
+                SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext());
+        final float[] weightOfLangModelVsSpatialModel =
+                new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
+                if (null == dictionary) continue;
+                final float weightForLocale = composer.isBatchMode()
+                        ? dictionaryGroup.mWeightForGesturingInLocale
+                        : dictionaryGroup.mWeightForTypingInLocale;
+                final ArrayList<SuggestedWordInfo> dictionarySuggestions =
+                        dictionary.getSuggestions(composer.getComposedDataSnapshot(), ngramContext,
+                                proximityInfoHandle, settingsValuesForSuggestion, sessionId,
+                                weightForLocale, weightOfLangModelVsSpatialModel);
+                if (null == dictionarySuggestions) continue;
+                suggestionResults.addAll(dictionarySuggestions);
+                if (null != suggestionResults.mRawSuggestions) {
+                    suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
+                }
+            }
+        }
+        return suggestionResults;
+    }
+
+    public boolean isValidWord(final String word, final boolean ignoreCase) {
+        if (TextUtils.isEmpty(word)) {
+            return false;
+        }
+        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            if (dictionaryGroup.mLocale == null) {
+                continue;
+            }
+            final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
+            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+                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)
+                        || (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private int getFrequencyInternal(final String word,
+            final boolean isGettingMaxFrequencyOfExactMatches) {
+        if (TextUtils.isEmpty(word)) {
+            return Dictionary.NOT_A_PROBABILITY;
+        }
+        int maxFreq = Dictionary.NOT_A_PROBABILITY;
+        final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+        for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
+            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+                final Dictionary dictionary = dictionaryGroup.getDict(dictType);
+                if (dictionary == null) continue;
+                final int tempFreq;
+                if (isGettingMaxFrequencyOfExactMatches) {
+                    tempFreq = dictionary.getMaxFrequencyOfExactMatches(word);
+                } else {
+                    tempFreq = dictionary.getFrequency(word);
+                }
+                if (tempFreq >= maxFreq) {
+                    maxFreq = tempFreq;
+                }
+            }
+        }
+        return maxFreq;
+    }
+
+    public int getFrequency(final String word) {
+        return getFrequencyInternal(word, false /* isGettingMaxFrequencyOfExactMatches */);
+    }
+
+    public int getMaxFrequencyOfExactMatches(final String word) {
+        return getFrequencyInternal(word, true /* isGettingMaxFrequencyOfExactMatches */);
+    }
+
+    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();
+            }
+        }
+    }
+
+    public void clearUserHistoryDictionary() {
+        clearSubDictionary(Dictionary.TYPE_USER_HISTORY);
+    }
+
+    // This method gets called only when the IME receives a notification to remove the
+    // personalization dictionary.
+    public void clearPersonalizationDictionary() {
+        clearSubDictionary(Dictionary.TYPE_PERSONALIZATION);
+        mPersonalizationHelper.clearDictionariesToUpdate();
+    }
+
+    public void clearContextualDictionary() {
+        clearSubDictionary(Dictionary.TYPE_CONTEXTUAL);
+    }
+
+    public void addEntriesToPersonalizationDictionary(
+            final PersonalizationDataChunk personalizationDataChunk,
+            final SpacingAndPunctuations spacingAndPunctuations,
+            final UpdateEntriesForInputEventsCallback callback) {
+        mPersonalizationHelper.updateEntriesOfPersonalizationDictionaries(
+                getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations,
+                callback);
+    }
+
+    @UsedForTesting
+    public void addPhraseToContextualDictionary(final String[] phrase, final int probability,
+            final int bigramProbabilityForWords, final int bigramProbabilityForPhrases) {
+        // TODO: we're inserting the phrase into the dictionary for the active language. Rethink
+        // this a bit from a theoretical point of view.
+        final ExpandableBinaryDictionary contextualDict =
+                getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
+        if (contextualDict == null) {
+            return;
+        }
+        NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE;
+        for (int i = 0; i < phrase.length; i++) {
+            final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length);
+            final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase);
+            contextualDict.addUnigramEntryWithCheckingDistracter(
+                    subPhraseStr, probability, null /* shortcutTarget */,
+                    Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
+                    false /* isNotAWord */, false /* isPossiblyOffensive */,
+                    BinaryDictionary.NOT_A_VALID_TIMESTAMP,
+                    DistracterFilter.EMPTY_DISTRACTER_FILTER);
+            contextualDict.addNgramEntry(ngramContext, subPhraseStr,
+                    bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+
+            if (i < phrase.length - 1) {
+                contextualDict.addUnigramEntryWithCheckingDistracter(
+                        phrase[i], probability, null /* shortcutTarget */,
+                        Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
+                        false /* isNotAWord */, false /* isPossiblyOffensive */,
+                        BinaryDictionary.NOT_A_VALID_TIMESTAMP,
+                        DistracterFilter.EMPTY_DISTRACTER_FILTER);
+                contextualDict.addNgramEntry(ngramContext, phrase[i],
+                        bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+            }
+            ngramContext =
+                    ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i]));
+        }
+    }
+
+    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();
+        }
+    }
+
+    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 : SUB_DICT_TYPES) {
+                final ExpandableBinaryDictionary dictionary = dictionaryGroup.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 3119ff8..13bd151 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
@@ -136,7 +136,7 @@
             if (dictionaryFacilitator != null) {
                 return dictionaryFacilitator;
             }
-            dictionaryFacilitator = new DictionaryFacilitator();
+            dictionaryFacilitator = DictionaryFacilitatorProvider.newDictionaryFacilitator();
             resetDictionariesForLocaleLocked(dictionaryFacilitator, locale);
             waitForLoadingMainDictionary(dictionaryFacilitator);
             mLruCache.put(locale, dictionaryFacilitator);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2e6541f..622cdb0 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -139,8 +139,8 @@
     private static final String SCHEME_PACKAGE = "package";
 
     final Settings mSettings;
-    private final DictionaryFacilitator mDictionaryFacilitator =
-            new DictionaryFacilitator(this /* context */);
+  private final DictionaryFacilitator mDictionaryFacilitator =
+      DictionaryFacilitatorProvider.newDictionaryFacilitator(this /* context */);
     // TODO: Move from LatinIME.
     private final PersonalizationDictionaryUpdater mPersonalizationDictionaryUpdater =
             new PersonalizationDictionaryUpdater(this /* context */, mDictionaryFacilitator);
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index b788d7f..a56de1f 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -28,7 +28,7 @@
 import android.preference.TwoStatePreference;
 
 import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver;
-import com.android.inputmethod.latin.DictionaryFacilitator;
+import com.android.inputmethod.latin.DictionaryFacilitatorImpl;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug;
 import com.android.inputmethod.latin.utils.ApplicationUtils;
@@ -67,7 +67,7 @@
 
         final PreferenceGroup dictDumpPreferenceGroup =
                 (PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS);
-        for (final String dictName : DictionaryFacilitator.DICT_TYPE_TO_CLASS.keySet()) {
+        for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) {
             final Preference pref = new DictDumpPreference(getActivity(), dictName);
             pref.setOnPreferenceClickListener(this);
             dictDumpPreferenceGroup.addPreference(pref);
diff --git a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
index 9d211c9..b9ce78d 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
@@ -25,6 +25,7 @@
 
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.DictionaryFacilitator;
+import com.android.inputmethod.latin.DictionaryFacilitatorProvider;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary;
 
 import android.test.AndroidTestCase;
@@ -40,7 +41,8 @@
     private DictionaryFacilitator getDictionaryFacilitator() {
         final ArrayList<String> dictTypes = new ArrayList<>();
         dictTypes.add(Dictionary.TYPE_CONTEXTUAL);
-        final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator();
+        final DictionaryFacilitator dictionaryFacilitator =
+            DictionaryFacilitatorProvider.newDictionaryFacilitator();
         dictionaryFacilitator.resetDictionariesForTesting(getContext(),
                 new Locale[] { LOCALE_EN_US }, dictTypes, new HashMap<String, File>(),
                 Collections.<String, Map<String, String>>emptyMap(), null /* account */);
diff --git a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
index b133d61..548167f 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
@@ -29,6 +29,7 @@
 import com.android.inputmethod.latin.BinaryDictionary;
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.DictionaryFacilitator;
+import com.android.inputmethod.latin.DictionaryFacilitatorProvider;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary;
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
@@ -55,7 +56,8 @@
         final ArrayList<String> dictTypes = new ArrayList<>();
         dictTypes.add(Dictionary.TYPE_MAIN);
         dictTypes.add(Dictionary.TYPE_PERSONALIZATION);
-        final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator(getContext());
+        final DictionaryFacilitator dictionaryFacilitator =
+                DictionaryFacilitatorProvider.newDictionaryFacilitator(getContext());
         dictionaryFacilitator.resetDictionariesForTesting(getContext(),
                 new Locale[] { LOCALE_EN_US }, dictTypes, new HashMap<String, File>(),
                 Collections.<String, Map<String, String>>emptyMap(), null /* account */);
