diff --git a/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index c9e158c4c409794e7dc438eb6a66e60c7cca54b7..3076085e44b347c923562d9d5b3b2463a3cf1473 100644
--- a/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -38,6 +38,7 @@ using namespace android;
 static jfieldID sDescriptorField;
 static jfieldID sAssetManagerNativeField;
 static jmethodID sAddWordMethod;
+static jfieldID sDictLength;
 
 //
 // helper function to throw an exception
@@ -79,6 +80,7 @@ static jint latinime_BinaryDictionary_open
     }
     Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier);
     dictionary->setAsset(dictAsset);
+    env->SetIntField(object, sDictLength, (jint) dictAsset->getLength());
 
     env->ReleaseStringUTFChars(resourceString, resourcePath);
     return (jint) dictionary;
@@ -176,6 +178,14 @@ static int registerNatives(JNIEnv *env)
     }
     sAssetManagerNativeField = env->GetFieldID(clazz, "mObject", "I");
 
+    // Get the field pointer for the dictionary length
+    clazz = env->FindClass(kClassPathName);
+    if (clazz == NULL) {
+        LOGE("Can't find %s", kClassPathName);
+        return -1;
+    }
+    sDictLength = env->GetFieldID(clazz, "mDictLength", "I");
+
     return registerNativeMethods(env,
             kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
 }
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b56463ed9bfb7d3f59e7d4fc05772767616cc312
--- /dev/null
+++ b/res/values-fr-rCA/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string>
+</resources>
diff --git a/res/xml-ru/kbd_qwerty.xml b/res/xml-ru/kbd_qwerty.xml
index c0afbd7b779a11457e8ee655fbb6dc8df805a3f5..9a42d421c67c1dc553e5538698eac19677bc72b0 100755
--- a/res/xml-ru/kbd_qwerty.xml
+++ b/res/xml-ru/kbd_qwerty.xml
@@ -31,7 +31,9 @@
         <Key android:keyLabel="ц"/>
         <Key android:keyLabel="у"/>
         <Key android:keyLabel="к"/>
-        <Key android:keyLabel="е"/>
+        <Key android:keyLabel="е"
+                android:popupKeyboard="@xml/kbd_popup_template"
+                android:popupCharacters="Ñ‘" />
         <Key android:keyLabel="н"/>
         <Key android:keyLabel="г"/>
         <Key android:keyLabel="ш"/>
@@ -40,7 +42,7 @@
         <Key android:keyLabel="Ñ…"
                 android:keyEdgeFlags="right"/>
     </Row>
-    
+
     <Row>
         <Key android:keyLabel="Ñ„"
                 android:keyEdgeFlags="left"/>
diff --git a/src/com/android/inputmethod/latin/BinaryDictionary.java b/src/com/android/inputmethod/latin/BinaryDictionary.java
index 36991845c66ef00bb5d58bf59acf426236d21d47..68d8b740cd380458e8aa9bd7995f7c435a972ef8 100644
--- a/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -35,6 +35,7 @@ public class BinaryDictionary extends Dictionary {
     private static final boolean ENABLE_MISSED_CHARACTERS = true;
 
     private int mNativeDict;
+    private int mDictLength; // This value is set from native code, don't change the name!!!!
     private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
     private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
     private int[] mFrequencies = new int[MAX_WORDS];
@@ -125,6 +126,10 @@ public class BinaryDictionary extends Dictionary {
         return isValidWordNative(mNativeDict, chars, chars.length);
     }
 
+    public int getSize() {
+        return mDictLength; // This value is initialized on the call to openNative()
+    }
+
     @Override
     public synchronized void close() {
         if (mNativeDict != 0) {
diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java
index f95ca1cbb5b411c1aa2047eaa13b6df3c77a5af3..22f843c1eb020a374060bd135bec200f1df82f96 100644
--- a/src/com/android/inputmethod/latin/LatinIME.java
+++ b/src/com/android/inputmethod/latin/LatinIME.java
@@ -126,7 +126,9 @@ public class LatinIME extends InputMethodService
     private CharSequence mBestWord;
     private boolean mPredictionOn;
     private boolean mCompletionOn;
+    private boolean mHasDictionary;
     private boolean mAutoSpace;
+    private boolean mAutoCorrectEnabled;
     private boolean mAutoCorrectOn;
     private boolean mCapsLock;
     private boolean mVibrateOn;
@@ -224,7 +226,6 @@ public class LatinIME extends InputMethodService
             mSuggest.close();
         }
         mSuggest = new Suggest(this, R.raw.main);
-        mSuggest.setCorrectionMode(mCorrectionMode);
         mUserDictionary = new UserDictionary(this);
         if (mContactsDictionary == null) {
             mContactsDictionary = new ContactsDictionary(this);
@@ -236,7 +237,7 @@ public class LatinIME extends InputMethodService
         mSuggest.setUserDictionary(mUserDictionary);
         mSuggest.setContactsDictionary(mContactsDictionary);
         mSuggest.setAutoDictionary(mAutoDictionary);
-        
+        updateCorrectionMode();
         mWordSeparators = mResources.getString(R.string.word_separators);
         mSentenceSeparators = mResources.getString(R.string.sentence_separators);
 
@@ -304,7 +305,7 @@ public class LatinIME extends InputMethodService
 
         TextEntryState.newSession(this);
 
-        boolean disableAutoCorrect = false;
+        mInputTypeNoAutoCorrect = false;
         mPredictionOn = false;
         mCompletionOn = false;
         mCompletions = null;
@@ -353,19 +354,19 @@ public class LatinIME extends InputMethodService
                     // If it's a browser edit field and auto correct is not ON explicitly, then
                     // disable auto correction, but keep suggestions on.
                     if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
-                        disableAutoCorrect = true;
+                        mInputTypeNoAutoCorrect = true;
                     }
                 }
 
                 // If NO_SUGGESTIONS is set, don't do prediction.
                 if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
                     mPredictionOn = false;
-                    disableAutoCorrect = true;
+                    mInputTypeNoAutoCorrect = true;
                 }
                 // If it's not multiline and the autoCorrect flag is not set, then don't correct
                 if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
                         (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
-                    disableAutoCorrect = true;
+                    mInputTypeNoAutoCorrect = true;
                 }
                 if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
                     mPredictionOn = false;
@@ -385,17 +386,13 @@ public class LatinIME extends InputMethodService
         setCandidatesViewShown(false);
         if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false);
         loadSettings();
-        // Override auto correct
-        if (disableAutoCorrect) {
-            mAutoCorrectOn = false;
-            if (mCorrectionMode == Suggest.CORRECTION_FULL) {
-                mCorrectionMode = Suggest.CORRECTION_BASIC;
-            }
-        }
+
+        // If the dictionary is not big enough, don't auto correct
+        mHasDictionary = mSuggest.hasMainDictionary();
+
+        updateCorrectionMode();
+
         mInputView.setProximityCorrectionEnabled(true);
-        if (mSuggest != null) {
-            mSuggest.setCorrectionMode(mCorrectionMode);
-        }
         mPredictionOn = mPredictionOn && mCorrectionMode > 0;
         checkTutorial(attribute.privateImeOptions);
         if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
@@ -1150,6 +1147,18 @@ public class LatinIME extends InputMethodService
         mUserDictionary.addWord(word, frequency);
     }
 
+    private void updateCorrectionMode() {
+        mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
+        mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
+                && !mInputTypeNoAutoCorrect && mHasDictionary;
+        mCorrectionMode = mAutoCorrectOn
+                ? Suggest.CORRECTION_FULL
+                : (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
+        if (mSuggest != null) {
+            mSuggest.setCorrectionMode(mCorrectionMode);
+        }
+    }
+
     private void launchSettings() {
         handleClose();
         Intent intent = new Intent();
@@ -1169,12 +1178,9 @@ public class LatinIME extends InputMethodService
         // will continue to work
         if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
         mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes;
-        boolean autoComplete = sp.getBoolean(PREF_AUTO_COMPLETE,
+        mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE,
                 mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
-        mAutoCorrectOn = mSuggest != null && (autoComplete || mQuickFixes);
-        mCorrectionMode = autoComplete
-                ? Suggest.CORRECTION_FULL
-                : (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
+        updateCorrectionMode();
         String languageList = sp.getString(PREF_SELECTED_LANGUAGES, null);
         updateSelectedLanguages(languageList);
     }
@@ -1274,6 +1280,7 @@ public class LatinIME extends InputMethodService
     private static final int CPS_BUFFER_SIZE = 16;
     private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
     private int mCpsIndex;
+    private boolean mInputTypeNoAutoCorrect;
     
     private void measureCps() {
         if (!LatinIME.PERF_DEBUG) return;
diff --git a/src/com/android/inputmethod/latin/Suggest.java b/src/com/android/inputmethod/latin/Suggest.java
index cc9a39cb77ec91a215915da0353dcc75665baacc..002f23064c41c935ffcab0d471967ae00f6e9f38 100755
--- a/src/com/android/inputmethod/latin/Suggest.java
+++ b/src/com/android/inputmethod/latin/Suggest.java
@@ -37,7 +37,9 @@ public class Suggest implements Dictionary.WordCallback {
     public static final int CORRECTION_BASIC = 1;
     public static final int CORRECTION_FULL = 2;
 
-    private Dictionary mMainDict;
+    private static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
+
+    private BinaryDictionary mMainDict;
 
     private Dictionary mUserDictionary;
 
@@ -49,9 +51,7 @@ public class Suggest implements Dictionary.WordCallback {
 
     private int[] mPriorities = new int[mPrefMaxSuggestions];
     private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
-    private boolean mIncludeTypedWordIfValid;
     private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
-    private Context mContext;
     private boolean mHaveCorrection;
     private CharSequence mOriginalWord;
     private String mLowerOriginalWord;
@@ -60,7 +60,6 @@ public class Suggest implements Dictionary.WordCallback {
 
 
     public Suggest(Context context, int dictionaryResId) {
-        mContext = context;
         mMainDict = new BinaryDictionary(context, dictionaryResId);
         for (int i = 0; i < mPrefMaxSuggestions; i++) {
             StringBuilder sb = new StringBuilder(32);
@@ -76,6 +75,10 @@ public class Suggest implements Dictionary.WordCallback {
         mCorrectionMode = mode;
     }
 
+    public boolean hasMainDictionary() {
+        return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
+    }
+
     /**
      * Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
      * before the main dictionary, if set.
@@ -155,7 +158,6 @@ public class Suggest implements Dictionary.WordCallback {
         mHaveCorrection = false;
         collectGarbage();
         Arrays.fill(mPriorities, 0);
-        mIncludeTypedWordIfValid = includeTypedWordIfValid;
         
         // Save a lowercase version of the original word
         mOriginalWord = wordComposer.getTypedWord();