diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index c9bcfe3698043955ab542f36d49338c00988e638..aa8bb2ccbcda4f7ced1df4d94d8898f19252c707 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -36,6 +36,7 @@ import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 // TODO: Consolidate dictionaries in native code.
@@ -55,8 +56,7 @@ public class DictionaryFacilitatorForSuggest {
     private UserHistoryDictionary mUserHistoryDictionary;
     private PersonalizationDictionary mPersonalizationDictionary;
 
-    @UsedForTesting
-    private boolean mIsCurrentlyWaitingForMainDictionary = false;
+    private final CountDownLatch mLatchForWaitingLoadingMainDictionary;
 
     public interface DictionaryInitializationListener {
         public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
@@ -77,12 +77,40 @@ public class DictionaryFacilitatorForSuggest {
             final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
         mContext = context;
         mLocale = locale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
         initForDebug(settingsValues);
-        reloadMainDict(context, locale, listener);
+        loadMainDict(context, locale, listener);
         setUserDictionary(new UserBinaryDictionary(context, locale));
         resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues);
     }
 
+    /**
+     * Creates instance for reloading the main dict.
+     *
+     * @param listener the listener
+     * @param oldDictionaryFacilitator the instance having old dictionaries. This must not be null.
+     */
+    public DictionaryFacilitatorForSuggest(final DictionaryInitializationListener listener,
+            final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
+        mContext = oldDictionaryFacilitator.mContext;
+        mLocale = oldDictionaryFacilitator.mLocale;
+        mDictionarySubsetForDebug = oldDictionaryFacilitator.mDictionarySubsetForDebug;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
+        loadMainDict(mContext, mLocale, listener);
+        // Transfer user dictionary.
+        setUserDictionary(oldDictionaryFacilitator.mUserDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER);
+        // Transfer contacts dictionary.
+        setContactsDictionary(oldDictionaryFacilitator.mContactsDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_CONTACTS);
+        // Transfer user history dictionary.
+        setUserHistoryDictionary(oldDictionaryFacilitator.mUserHistoryDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER_HISTORY);
+        // Transfer personalization dictionary.
+        setPersonalizationDictionary(oldDictionaryFacilitator.mPersonalizationDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_PERSONALIZATION);
+    }
+
     /**
      * Creates instance for when the settings values have been changed.
      *
@@ -94,6 +122,7 @@ public class DictionaryFacilitatorForSuggest {
             final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
         mContext = oldDictionaryFacilitator.mContext;
         mLocale = oldDictionaryFacilitator.mLocale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
         initForDebug(settingsValues);
         // Transfer main dictionary.
         setMainDictionary(oldDictionaryFacilitator.mMainDictionary);
@@ -110,6 +139,7 @@ public class DictionaryFacilitatorForSuggest {
             final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles) {
         mContext = context;
         mLocale = locale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
         for (final String dictType : dictionaryTypes) {
             if (dictType.equals(Dictionary.TYPE_MAIN)) {
                 final DictionaryCollection mainDictionary =
@@ -167,9 +197,8 @@ public class DictionaryFacilitatorForSuggest {
         }
     }
 
-    public void reloadMainDict(final Context context, final Locale locale,
+    private void loadMainDict(final Context context, final Locale locale,
             final DictionaryInitializationListener listener) {
-        mIsCurrentlyWaitingForMainDictionary = true;
         mMainDictionary = null;
         if (listener != null) {
             listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
@@ -183,7 +212,7 @@ public class DictionaryFacilitatorForSuggest {
                 if (listener != null) {
                     listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
                 }
-                mIsCurrentlyWaitingForMainDictionary = false;
+                mLatchForWaitingLoadingMainDictionary.countDown();
             }
         }.start();
     }
@@ -194,9 +223,9 @@ public class DictionaryFacilitatorForSuggest {
         return null != mMainDictionary && mMainDictionary.isInitialized();
     }
 
-    @UsedForTesting
-    public boolean isCurrentlyWaitingForMainDictionary() {
-        return mIsCurrentlyWaitingForMainDictionary;
+    public void waitForLoadingMainDictionary(final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        mLatchForWaitingLoadingMainDictionary.await(timeout, unit);
     }
 
     private void setMainDictionary(final Dictionary mainDictionary) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b7f03574781b974d016c1a66201933ef83aa6e91..aadb65192084a920be5c1a887b36aa1ea7639fba 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -89,6 +89,7 @@ import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Input method implementation for Qwerty'ish keyboard.
@@ -519,10 +520,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     new DictionaryFacilitatorForSuggest(currentSettingsValues,
                             oldDictionaryFacilitator);
             // Create Suggest instance with the new dictionary facilitator.
-            mInputLogic.mSuggest = new Suggest(suggest /* oldSuggest */, dictionaryFacilitator);
-            suggest.close();
+            resetSuggest(new Suggest(suggest /* oldSuggest */, dictionaryFacilitator));
+        } else if (suggest == null) {
+            initSuggestForLocale(locale);
         }
-        if (currentSettingsValues.mUsePersonalizedDicts) {
+    }
+
+    private void refreshPersonalizationDictionarySession() {
+        if (mSettings.getCurrent().mUsePersonalizedDicts) {
             if (mSubtypeSwitcher.isSystemLocaleSameAsLocaleOfAllEnabledSubtypes()) {
                 final DictionaryFacilitatorForSuggest dictionaryFacilitator =
                         (mInputLogic.mSuggest == null) ?
@@ -562,33 +567,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         } else {
             subtypeLocale = switcherSubtypeLocale;
         }
+        initSuggestForLocale(subtypeLocale);
+    }
 
+    private void initSuggestForLocale(final Locale locale) {
         final SettingsValues settingsValues = mSettings.getCurrent();
         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,
+                new DictionaryFacilitatorForSuggest(this /* context */, locale,
                         settingsValues, this /* DictionaryInitializationListener */,
                         oldDictionaryFacilitator);
-        PersonalizationDictionarySessionRegistrar.onConfigurationChanged(
-                this, getResources().getConfiguration(), dictionaryFacilitator);
-        final Suggest newSuggest = new Suggest(subtypeLocale, dictionaryFacilitator);
+        final Suggest newSuggest = new Suggest(locale, dictionaryFacilitator);
         if (settingsValues.mCorrectionEnabled) {
             newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
         }
+        resetSuggest(newSuggest);
+    }
+
+    /* package private */ void resetSuggestMainDict() {
+        final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                mInputLogic.mSuggest.mDictionaryFacilitator;
+        final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                new DictionaryFacilitatorForSuggest(this /* listener */, oldDictionaryFacilitator);
+        resetSuggest(new Suggest(mInputLogic.mSuggest /* oldSuggest */, dictionaryFacilitator));
+    }
+
+    private void resetSuggest(final Suggest newSuggest) {
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator);
         }
         final Suggest oldSuggest = mInputLogic.mSuggest;
         mInputLogic.mSuggest = newSuggest;
         if (oldSuggest != null) oldSuggest.close();
-    }
-
-    /* package private */ void resetSuggestMainDict() {
-        final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
-        mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, subtypeLocale,
-                this /* SuggestInitializationListener */);
+        refreshPersonalizationDictionarySession();
     }
 
     @Override
@@ -1789,14 +1802,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME.
     @UsedForTesting
-    /* package for test */ boolean isCurrentlyWaitingForMainDictionary() {
-        return mInputLogic.mSuggest.mDictionaryFacilitator.isCurrentlyWaitingForMainDictionary();
+    /* package for test */ void waitForMainDictionary(final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary(timeout, unit);
     }
 
     // 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.reloadMainDict(this, locale, null);
+    /* package for test */ void replaceDictionariesForTest(final Locale locale) {
+        final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                mInputLogic.mSuggest.mDictionaryFacilitator;
+        final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                new DictionaryFacilitatorForSuggest(this, locale, mSettings.getCurrent(),
+                        this /* listener */, oldDictionaryFacilitator);
+        resetSuggest(new Suggest(locale, dictionaryFacilitator));
     }
 
     public void debugDumpStateAndCrashWithException(final String context) {
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index cee73c917071704c8c11a059037c52180a83134c..84e8a862ce5883410da9c62c872c3f452ddafb2a 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -25,6 +25,7 @@ import android.text.InputType;
 import android.text.SpannableStringBuilder;
 import android.text.style.CharacterStyle;
 import android.text.style.SuggestionSpan;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,8 +42,10 @@ import com.android.inputmethod.latin.utils.LocaleUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
+    private static final String TAG = InputTestsBase.class.getSimpleName();
 
     private static final String PREF_DEBUG_MODE = "debug_mode";
     private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
@@ -54,6 +57,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
     protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500;
     // The message that sets predictions is posted with a 200 ms delay
     protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200;
+    private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60;
 
     protected LatinIME mLatinIME;
     protected Keyboard mKeyboard;
@@ -260,15 +264,11 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
     }
 
     protected void waitForDictionaryToBeLoaded() {
-        int remainingAttempts = 300;
-        while (remainingAttempts > 0 && mLatinIME.isCurrentlyWaitingForMainDictionary()) {
-            try {
-                Thread.sleep(200);
-            } catch (InterruptedException e) {
-                // Don't do much
-            } finally {
-                --remainingAttempts;
-            }
+        try {
+            mLatinIME.waitForMainDictionary(
+                    TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Interrupted during waiting for loading main dictionary.", e);
         }
     }
 
@@ -300,8 +300,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
             final String dictLocale) {
         changeLanguage(keyboardLocale);
         if (!keyboardLocale.equals(dictLocale)) {
-            mLatinIME.replaceMainDictionaryForTest(
-                    LocaleUtils.constructLocaleFromString(dictLocale));
+            mLatinIME.replaceDictionariesForTest(LocaleUtils.constructLocaleFromString(dictLocale));
         }
         waitForDictionaryToBeLoaded();
     }