merge in master-release history after reset to 23246ed18d9b26d8a7673140c00e060022be935b
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 74b83c1..d100d32 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -140,10 +140,10 @@
     private final SubtypeState mSubtypeState = new SubtypeState();
 
     // Object for reacting to adding/removing a dictionary pack.
-    private BroadcastReceiver mDictionaryPackInstallReceiver =
+    private final BroadcastReceiver mDictionaryPackInstallReceiver =
             new DictionaryPackInstallBroadcastReceiver(this);
 
-    private BroadcastReceiver mDictionaryDumpBroadcastReceiver =
+    private final BroadcastReceiver mDictionaryDumpBroadcastReceiver =
             new DictionaryDumpBroadcastReceiver(this);
 
     private AlertDialog mOptionsDialog;
@@ -1629,7 +1629,8 @@
     // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event);
 
     // receive ringer mode change and network state change.
-    private BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mConnectivityAndRingerModeChangeReceiver =
+            new BroadcastReceiver() {
         @Override
         public void onReceive(final Context context, final Intent intent) {
             final String action = intent.getAction();
@@ -1746,8 +1747,7 @@
 
     @UsedForTesting
     /* package for test */ DistracterFilter createDistracterFilter() {
-        return DistracterFilterUtils.createDistracterFilter(
-                mInputLogic.mSuggest, mKeyboardSwitcher);
+        return DistracterFilterUtils.createDistracterFilter(this /* Context */, mKeyboardSwitcher);
     }
 
     public void dumpDictionaryForDebug(final String dictName) {
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
index dc3e9bf..05387d5 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
@@ -16,6 +16,12 @@
 
 package com.android.inputmethod.latin.utils;
 
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import android.content.Context;
+import android.util.Log;
+
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.Suggest;
@@ -29,6 +35,11 @@
  * or user history dictionaries
  */
 public class DistracterFilter {
+    private static final String TAG = DistracterFilter.class.getSimpleName();
+
+    private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120;
+
+    private final Context mContext;
     private final Suggest mSuggest;
     private final Keyboard mKeyboard;
 
@@ -42,13 +53,13 @@
     /**
      * Create a DistracterFilter instance.
      *
-     * @param suggest an instance of Suggest which will be used to obtain a list of suggestions
-     *                for a potential distracter
+     * @param context the context.
      * @param keyboard the keyboard that is currently being used. This information is needed
      *                 when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions.
      */
-    public DistracterFilter(final Suggest suggest, final Keyboard keyboard) {
-        mSuggest = suggest;
+    public DistracterFilter(final Context context, final Keyboard keyboard) {
+        mContext = context;
+        mSuggest = new Suggest();
         mKeyboard = keyboard;
     }
 
@@ -66,19 +77,37 @@
         return false;
     }
 
+    private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException {
+        mSuggest.mDictionaryFacilitator.resetDictionaries(mContext, newlocale,
+                false /* useContactsDict */, false /* usePersonalizedDicts */,
+                false /* forceReloadMainDictionary */, null /* listener */);
+        mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary(
+                TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS);
+    }
+
     /**
      * Determine whether a word is a distracter to words in dictionaries.
      *
      * @param prevWord the previous word, or null if none.
      * @param testedWord the word that will be tested to see whether it is a distracter to words
      *                   in dictionaries.
+     * @param locale the locale of words.
      * @return true if testedWord is a distracter, otherwise false.
      */
     public boolean isDistracterToWordsInDictionaries(final String prevWord,
-            final String testedWord) {
-        if (mSuggest == null || mKeyboard == null) {
+            final String testedWord, final Locale locale) {
+        if (mKeyboard == null || locale == null) {
             return false;
         }
+        if (!locale.equals(mSuggest.mDictionaryFacilitator.getLocale())) {
+            // Reset dictionaries for the locale.
+            try {
+                loadDictionariesForLocale(locale);
+            } catch (final InterruptedException e) {
+                Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter", e);
+                return false;
+            }
+        }
 
         final WordComposer composer = new WordComposer();
         final int[] codePoints = StringUtils.toCodePointArray(testedWord);
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java
index df07f97..8a711a2 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java
@@ -16,17 +16,18 @@
 
 package com.android.inputmethod.latin.utils;
 
+import android.content.Context;
+
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.Suggest;
 
 public class DistracterFilterUtils {
     private DistracterFilterUtils() {
         // This utility class is not publicly instantiable.
     }
 
-    public static final DistracterFilter createDistracterFilter(final Suggest suggest,
+    public static final DistracterFilter createDistracterFilter(final Context context,
             final KeyboardSwitcher keyboardSwitcher) {
         final MainKeyboardView mainKeyboardView = keyboardSwitcher.getMainKeyboardView();
         // TODO: Create Keyboard when mainKeyboardView is null.
@@ -34,7 +35,7 @@
         // spellchecker's logic.
         final Keyboard keyboard = (mainKeyboardView != null) ?
                 mainKeyboardView.getKeyboard() : null;
-        final DistracterFilter distracterFilter = new DistracterFilter(suggest, keyboard);
+        final DistracterFilter distracterFilter = new DistracterFilter(context, keyboard);
         return distracterFilter;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
index 74e7db9..2d6796e 100644
--- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
+++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
@@ -150,7 +150,7 @@
         // Adding such a word to dictonaries would interfere with entering in-dictionary words. For
         // example, adding "mot" to dictionaries might interfere with entering "not".
         // This kind of OOV should be filtered out.
-        if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord)) {
+        if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord, locale)) {
             return null;
         }
         return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp,
diff --git a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java b/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java
index 186542a..d7b57ae 100644
--- a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java
+++ b/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import java.util.Locale;
+
 import android.test.suitebuilder.annotation.LargeTest;
 
 import com.android.inputmethod.latin.utils.DistracterFilter;
@@ -35,39 +37,49 @@
 
     public void testIsDistractorToWordsInDictionaries() {
         final String EMPTY_PREV_WORD = null;
+
+        final Locale localeEnUs = new Locale("en", "US");
         String typedWord = "alot";
         // For this test case, we consider "alot" is a distracter to "a lot".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "mot";
         // For this test case, we consider "mot" is a distracter to "not".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "wierd";
         // For this test case, we consider "wierd" is a distracter to "weird".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "hoe";
         // For this test case, we consider "hoe" is a distracter to "how".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "nit";
         // For this test case, we consider "nit" is a distracter to "not".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "ill";
         // For this test case, we consider "ill" is a distracter to "I'll".
-        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+        assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
+                EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "asdfd";
         // For this test case, we consider "asdfd" is not a distracter to any word in dictionaries.
         assertFalse(
-                mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+                mDistracterFilter.isDistracterToWordsInDictionaries(
+                        EMPTY_PREV_WORD, typedWord, localeEnUs));
 
         typedWord = "thank";
         // For this test case, we consider "thank" is not a distracter to any other word
         // in dictionaries.
         assertFalse(
-                mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord));
+                mDistracterFilter.isDistracterToWordsInDictionaries(
+                        EMPTY_PREV_WORD, typedWord, localeEnUs));
     }
 }