diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index 3f6756e3934c18c52e00ad1d38c9851f7dc2e0b7..e8b9a796a68692e99eea01fd9813b593de795178 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -22,7 +22,6 @@ import android.util.Log;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.latin.Suggest.SuggestInitializationListener;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
 import com.android.inputmethod.latin.personalization.PersonalizationHelper;
@@ -45,7 +44,7 @@ public class DictionaryFacilitatorForSuggest {
 
     private final ConcurrentHashMap<String, Dictionary> mDictionaries =
             CollectionUtils.newConcurrentHashMap();
-    private HashSet<String> mOnlyDictionarySetForDebug = null;
+    private HashSet<String> mDictionarySubsetForDebug = null;
 
     private Dictionary mMainDictionary;
     private ContactsBinaryDictionary mContactsDictionary;
@@ -56,17 +55,51 @@ public class DictionaryFacilitatorForSuggest {
     @UsedForTesting
     private boolean mIsCurrentlyWaitingForMainDictionary = false;
 
+    public interface DictionaryInitializationListener {
+        public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
+    }
+
+    /**
+     * Creates instance for initialization or when the locale is changed.
+     *
+     * @param context the context
+     * @param locale the locale
+     * @param settingsValues current settings values to control what dictionaries should be used
+     * @param listener the listener
+     * @param oldDictionaryFacilitator the instance having old dictionaries. This is null when the
+     * instance is initially created.
+     */
     public DictionaryFacilitatorForSuggest(final Context context, final Locale locale,
-            final SettingsValues settingsValues, final SuggestInitializationListener listener) {
-        resetMainDict(context, locale, listener);
+            final SettingsValues settingsValues, final DictionaryInitializationListener listener,
+            final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
         mContext = context;
         mLocale = locale;
-        // initialize a debug flag for the personalization
-        if (settingsValues.mUseOnlyPersonalizationDictionaryForDebug) {
-            mOnlyDictionarySetForDebug = new HashSet<String>();
-            mOnlyDictionarySetForDebug.add(Dictionary.TYPE_PERSONALIZATION);
-        }
+        initForDebug(settingsValues);
+        reloadMainDict(context, locale, listener);
         setUserDictionary(new UserBinaryDictionary(context, locale));
+        resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues);
+    }
+
+    /**
+     * Creates instance for when the settings values have been changed.
+     *
+     * @param settingsValues the new settings values
+     * @param oldDictionaryFacilitator the instance having old dictionaries. This must not be null.
+     */
+    //
+    public DictionaryFacilitatorForSuggest(final SettingsValues settingsValues,
+            final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
+        mContext = oldDictionaryFacilitator.mContext;
+        mLocale = oldDictionaryFacilitator.mLocale;
+        initForDebug(settingsValues);
+        // Transfer main dictionary.
+        setMainDictionary(oldDictionaryFacilitator.mMainDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_MAIN);
+        // Transfer user dictionary.
+        setUserDictionary(oldDictionaryFacilitator.mUserDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER);
+        // Transfer or create additional dictionaries depending on the settings values.
+        resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues);
     }
 
     @UsedForTesting
@@ -76,8 +109,15 @@ public class DictionaryFacilitatorForSuggest {
                 false /* useFullEditDistance */, locale);
         mContext = context;
         mLocale = locale;
-        mMainDictionary = mainDict;
-        addOrReplaceDictionary(Dictionary.TYPE_MAIN, mainDict);
+        setMainDictionary(mainDict);
+    }
+
+    // initialize a debug flag for the personalization
+    private void initForDebug(final SettingsValues settingsValues) {
+        if (settingsValues.mUseOnlyPersonalizationDictionaryForDebug) {
+            mDictionarySubsetForDebug = new HashSet<String>();
+            mDictionarySubsetForDebug.add(Dictionary.TYPE_PERSONALIZATION);
+        }
     }
 
     public void close() {
@@ -86,15 +126,10 @@ public class DictionaryFacilitatorForSuggest {
         for (final Dictionary dictionary : dictionaries) {
             dictionary.close();
         }
-        mMainDictionary = null;
-        mContactsDictionary = null;
-        mUserDictionary = null;
-        mUserHistoryDictionary = null;
-        mPersonalizationDictionary = null;
     }
 
-    public void resetMainDict(final Context context, final Locale locale,
-            final SuggestInitializationListener listener) {
+    public void reloadMainDict(final Context context, final Locale locale,
+            final DictionaryInitializationListener listener) {
         mIsCurrentlyWaitingForMainDictionary = true;
         mMainDictionary = null;
         if (listener != null) {
@@ -163,12 +198,12 @@ public class DictionaryFacilitatorForSuggest {
     }
 
     /**
-     * Set dictionaries that can be turned off according to the user settings.
+     * Reset dictionaries that can be turned off according to the user settings.
      *
      * @param oldDictionaryFacilitator the instance having old dictionaries
      * @param settingsValues current SettingsValues
      */
-    public void setAdditionalDictionaries(
+    private void resetAdditionalDictionaries(
             final DictionaryFacilitatorForSuggest oldDictionaryFacilitator,
             final SettingsValues settingsValues) {
         // Contacts dictionary
@@ -361,8 +396,12 @@ public class DictionaryFacilitatorForSuggest {
         return maxFreq;
     }
 
+    private void removeDictionary(final String key) {
+        mDictionaries.remove(key);
+    }
+
     private void addOrReplaceDictionary(final String key, final Dictionary dict) {
-        if (mOnlyDictionarySetForDebug != null && !mOnlyDictionarySetForDebug.contains(key)) {
+        if (mDictionarySubsetForDebug != null && !mDictionarySubsetForDebug.contains(key)) {
             Log.w(TAG, "Ignore add " + key + " dictionary for debug.");
             return;
         }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 77def63f1685b9ace4b0774e65f7f1289ccae595..7a4164cf1d114276af500b645450e6e95dd6f971 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -96,7 +96,8 @@ import java.util.Locale;
  * Input method implementation for Qwerty'ish keyboard.
  */
 public class LatinIME extends InputMethodService implements KeyboardActionListener,
-        SuggestionStripView.Listener, Suggest.SuggestInitializationListener {
+        SuggestionStripView.Listener,
+        DictionaryFacilitatorForSuggest.DictionaryInitializationListener {
     private static final String TAG = LatinIME.class.getSimpleName();
     private static final boolean TRACE = false;
     private static boolean DEBUG = false;
@@ -513,12 +514,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // be done later inside {@see #initSuggest()} when the reopenDictionaries message is
         // processed.
         final SettingsValues currentSettingsValues = mSettings.getCurrent();
-        if (!mHandler.hasPendingReopenDictionaries() && mInputLogic.mSuggest != null) {
+        final Suggest suggest = mInputLogic.mSuggest;
+        if (!mHandler.hasPendingReopenDictionaries() && suggest != null) {
             // May need to reset dictionaries depending on the user settings.
-            // TODO: Quit setting dictionaries from LatinIME.
-            mInputLogic.mSuggest.mDictionaryFacilitator.setAdditionalDictionaries(
-                    mInputLogic.mSuggest.mDictionaryFacilitator /* oldDictionaryFacilitator */,
-                    currentSettingsValues);
+            final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                    suggest.mDictionaryFacilitator;
+            final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                    new DictionaryFacilitatorForSuggest(currentSettingsValues,
+                            oldDictionaryFacilitator);
+            // Create Suggest instance with the new dictionary facilitator.
+            mInputLogic.mSuggest = new Suggest(suggest /* oldSuggest */, dictionaryFacilitator);
+            suggest.close();
         }
         if (currentSettingsValues.mUsePersonalizedDicts) {
             PersonalizationDictionarySessionRegistrar.init(this);
@@ -555,19 +561,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
 
         final SettingsValues settingsValues = mSettings.getCurrent();
-        final Suggest newSuggest = new Suggest(this /* Context */, subtypeLocale, settingsValues,
-                this /* SuggestInitializationListener */);
+        final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator;
+        // Creates new dictionary facilitator for the new locale.
+        final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                new DictionaryFacilitatorForSuggest(this /* context */, subtypeLocale,
+                        settingsValues, this /* DictionaryInitializationListener */,
+                        oldDictionaryFacilitator);
+        final Suggest newSuggest = new Suggest(subtypeLocale, dictionaryFacilitator);
         if (settingsValues.mCorrectionEnabled) {
             newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
         }
-
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator);
         }
-        // TODO: Quit setting dictionaries from LatinIME.
-        newSuggest.mDictionaryFacilitator.setAdditionalDictionaries(
-                (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator
-                        /* oldDictionaryFacilitator */, settingsValues);
         final Suggest oldSuggest = mInputLogic.mSuggest;
         mInputLogic.mSuggest = newSuggest;
         if (oldSuggest != null) oldSuggest.close();
@@ -575,7 +582,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     /* package private */ void resetSuggestMainDict() {
         final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
-        mInputLogic.mSuggest.mDictionaryFacilitator.resetMainDict(this, subtypeLocale,
+        mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, subtypeLocale,
                 this /* SuggestInitializationListener */);
     }
 
@@ -1974,7 +1981,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
     @UsedForTesting
     /* package for test */ void replaceMainDictionaryForTest(final Locale locale) {
-        mInputLogic.mSuggest.mDictionaryFacilitator.resetMainDict(this, locale, null);
+        mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, locale, null);
     }
 
     public void debugDumpStateAndCrashWithException(final String context) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 3f38323f909f7abf67c0738bd32c2a84197a34d5..5dc8f3053f39bdcc050b14544efc6f79e44d16c3 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -16,13 +16,10 @@
 
 package com.android.inputmethod.latin;
 
-import android.content.Context;
 import android.text.TextUtils;
 
-import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.settings.SettingsValues;
 import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
 import com.android.inputmethod.latin.utils.BoundedTreeSet;
 import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -55,10 +52,6 @@ public final class Suggest {
 
     public static final int MAX_SUGGESTIONS = 18;
 
-    public interface SuggestInitializationListener {
-        public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
-    }
-
     private static final boolean DBG = LatinImeLogger.sDBG;
 
     public final DictionaryFacilitatorForSuggest mDictionaryFacilitator;
@@ -68,18 +61,18 @@ public final class Suggest {
     // Locale used for upper- and title-casing words
     public final Locale mLocale;
 
-    public Suggest(final Context context, final Locale locale, final SettingsValues settingsValues,
-            final SuggestInitializationListener listener) {
+    public Suggest(final Locale locale,
+            final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
         mLocale = locale;
-        mDictionaryFacilitator = new DictionaryFacilitatorForSuggest(context, locale,
-                settingsValues, listener);
+        mDictionaryFacilitator = dictionaryFacilitator;
     }
 
-    @UsedForTesting
-    Suggest(final Context context, final AssetFileAddress[] dictionaryList, final Locale locale) {
-        mLocale = locale;
-        mDictionaryFacilitator = new DictionaryFacilitatorForSuggest(context, dictionaryList,
-                locale);
+    // Creates instance with new dictionary facilitator.
+    public Suggest(final Suggest oldSuggst,
+            final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
+        mLocale = oldSuggst.mLocale;
+        mAutoCorrectionThreshold = oldSuggst.mAutoCorrectionThreshold;
+        mDictionaryFacilitator = dictionaryFacilitator;
     }
 
     public void setAutoCorrectionThreshold(float threshold) {