Merge "Avoid NPE when logging the entry point to Settings"
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 54579f2..5655a55 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -62,9 +62,9 @@
     <string name="cloud_sync_summary_disabled">Sync your personal dictionary across devices</string>
     <!-- Option title for starting the sync cycle now. [CHAR LIMIT=33]-->
     <string name="sync_now_title">Sync now</string>
-    <!-- Option title for letting user delete data from Google servers.  [CHAR LIMIT=33] -->
-    <string name="clear_sync_data_title">Delete Keyboard Cloud data</string>
-    <!-- Option summary for letting user delete data from Google servers. [CHAR LIMIT=65] -->
+    <!-- Option title for letting user delete synced google keyboard data from Google servers.  [CHAR LIMIT=35] -->
+    <string name="clear_sync_data_title">Delete cloud data</string>
+    <!-- Option summary for letting user delete synced google keyboard data from Google servers. [CHAR LIMIT=65] -->
     <string name="clear_sync_data_summary">Deletes your synced data from Google</string>
     <!-- Text for confirmation dialog box asking user to confirm deletion of cloud data. [CHAR LIMIT=65] -->
     <string name="clear_sync_data_confirmation">Your synced data will be deleted from the cloud. Are you sure?</string>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 64929ad..0b0c93e 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -366,6 +366,7 @@
     />
     <!-- TODO: This Hinglish keyboard is a preliminary layout.
                This isn't based on the final specification. -->
+    <!--  Disabled because there is no LM yet, and this layout does not offer anything different.
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_hi_ZZ"
             android:subtypeId="0x352eb37c"
@@ -374,6 +375,7 @@
             android:imeSubtypeExtraValue="AsciiCapable,KeyboardLayoutSet=qwerty,EmojiCapable"
             android:isAsciiCapable="true"
     />
+    -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0x35b7526a"
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
index 14e0050..88ea4e6 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
@@ -28,6 +28,7 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
@@ -106,16 +107,27 @@
 
     @Override
     public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
-        final String metadataUri =
-                MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId);
-        // We only add the "Refresh" button if we have a non-empty URL to refresh from. If the
-        // URL is empty, of course we can't refresh so it makes no sense to display this.
-        if (!TextUtils.isEmpty(metadataUri)) {
-            mUpdateNowMenu =
-                    menu.add(Menu.NONE, MENU_UPDATE_NOW, 0, R.string.check_for_updates_now);
-            mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-            refreshNetworkState();
-        }
+        new AsyncTask<Void, Void, String>() {
+            @Override
+            protected String doInBackground(Void... params) {
+                return MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId);
+            }
+
+            @Override
+            protected void onPostExecute(String metadataUri) {
+                // We only add the "Refresh" button if we have a non-empty URL to refresh from. If
+                // the URL is empty, of course we can't refresh so it makes no sense to display
+                // this.
+                if (!TextUtils.isEmpty(metadataUri)) {
+                    if (mUpdateNowMenu == null) {
+                        mUpdateNowMenu = menu.add(Menu.NONE, MENU_UPDATE_NOW, 0,
+                                        R.string.check_for_updates_now);
+                        mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+                    }
+                    refreshNetworkState();
+                }
+            }
+        }.execute();
     }
 
     @Override
@@ -124,18 +136,25 @@
         mChangedSettings = false;
         UpdateHandler.registerUpdateEventListener(this);
         final Activity activity = getActivity();
-        if (!MetadataDbHelper.isClientKnown(activity, mClientId)) {
-            Log.i(TAG, "Unknown dictionary pack client: " + mClientId + ". Requesting info.");
-            final Intent unknownClientBroadcast =
-                    new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT);
-            unknownClientBroadcast.putExtra(
-                    DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId);
-            activity.sendBroadcast(unknownClientBroadcast);
-        }
         final IntentFilter filter = new IntentFilter();
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         getActivity().registerReceiver(mConnectivityChangedReceiver, filter);
         refreshNetworkState();
+
+        new Thread("onResume") {
+            @Override
+            public void run() {
+                if (!MetadataDbHelper.isClientKnown(activity, mClientId)) {
+                    Log.i(TAG, "Unknown dictionary pack client: " + mClientId
+                            + ". Requesting info.");
+                    final Intent unknownClientBroadcast =
+                            new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT);
+                    unknownClientBroadcast.putExtra(
+                            DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId);
+                    activity.sendBroadcast(unknownClientBroadcast);
+                }
+            }
+        }.start();
     }
 
     @Override
@@ -375,8 +394,13 @@
     private void cancelRefresh() {
         UpdateHandler.unregisterUpdateEventListener(this);
         final Context context = getActivity();
-        UpdateHandler.cancelUpdate(context, mClientId);
-        stopLoadingAnimation();
+        new Thread("cancelByHand") {
+            @Override
+            public void run() {
+                UpdateHandler.cancelUpdate(context, mClientId);
+                stopLoadingAnimation();
+            }
+        }.start();
     }
 
     private void startLoadingAnimation() {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 6b49f9a..d5dff10 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -17,7 +17,6 @@
 package com.android.inputmethod.latin;
 
 import android.content.Context;
-import android.util.Pair;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.Keyboard;
@@ -28,6 +27,7 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -172,5 +172,5 @@
 
     void dumpDictionaryForDebug(final String dictName);
 
-    ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts();
+    @Nonnull List<DictionaryStats> getDictionaryStats(final Context context);
 }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index e5d770a..9ce92da 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.Keyboard;
@@ -39,6 +38,7 @@
 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;
@@ -644,12 +644,12 @@
     }
 
     @Override
-    public ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts() {
-        final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
+    @Nonnull public List<DictionaryStats> getDictionaryStats(final Context context) {
+        final ArrayList<DictionaryStats> statsOfEnabledSubDicts = new ArrayList<>();
         for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
             final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictType);
             if (dictionary == null) continue;
-            statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
+            statsOfEnabledSubDicts.add(dictionary.getDictionaryStats());
         }
         return statsOfEnabledSubDicts;
     }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryStats.java b/java/src/com/android/inputmethod/latin/DictionaryStats.java
index 5dd39d3..a6b37aa 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryStats.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryStats.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.latin;
 
 import java.io.File;
+import java.math.BigDecimal;
 import java.util.Locale;
 
 public class DictionaryStats {
@@ -26,18 +27,54 @@
     public final String mDictName;
     public final String mDictFilePath;
     public final long mDictFileSize;
-
-    public final int mUnigramCount;
-    public final int mNgramCount;
-    // TODO: Add more members.
+    public final int mContentVersion;
 
     public DictionaryStats(final Locale locale, final String dictName, final File dictFile,
-            final int unigramCount, final int ngramCount) {
+            final int contentVersion) {
         mLocale = locale;
         mDictName = dictName;
-        mDictFilePath = dictFile.getAbsolutePath();
-        mDictFileSize = dictFile.length();
-        mUnigramCount = unigramCount;
-        mNgramCount = ngramCount;
+        mDictFilePath = (dictFile == null) ? null : dictFile.getName();
+        mDictFileSize = (dictFile == null || !dictFile.exists()) ? 0 : dictFile.length();
+        mContentVersion = contentVersion;
+    }
+
+    public String getFileSizeString() {
+        if (mDictFileSize == 0) {
+            return "0";
+        }
+        BigDecimal bytes = new BigDecimal(mDictFileSize);
+        BigDecimal kb = bytes.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP);
+        if (kb.longValue() == 0) {
+            return bytes.toString() + " bytes";
+        }
+        BigDecimal mb = kb.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP);
+        if (mb.longValue() == 0) {
+            return kb.toString() + " kb";
+        }
+        return mb.toString() + " Mb";
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder(mDictName);
+        if (mDictName.equals(Dictionary.TYPE_MAIN)) {
+            builder.append(" (");
+            builder.append(mContentVersion);
+            builder.append(")");
+        }
+        builder.append(": ");
+        builder.append(mDictFilePath);
+        builder.append(" / ");
+        builder.append(getFileSizeString());
+        return builder.toString();
+    }
+
+    public static String toString(final Iterable<DictionaryStats> stats) {
+        final StringBuilder builder = new StringBuilder("LM Stats");
+        for (DictionaryStats stat : stats) {
+            builder.append("\n    ");
+            builder.append(stat.toString());
+        }
+        return builder.toString();
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 80daedd..1ef7061 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -646,16 +646,6 @@
         });
     }
 
-    static int parseEntryCount(final String entryCountStr) {
-        int entryCount;
-        try {
-            entryCount = Integer.parseInt(entryCountStr);
-        } catch (final NumberFormatException e) {
-            entryCount = DictionaryStats.NOT_AN_ENTRY_COUNT;
-        }
-        return entryCount;
-    }
-
     public DictionaryStats getDictionaryStats() {
         reloadDictionaryIfRequired();
         final String dictName = mDictName;
@@ -664,22 +654,7 @@
         asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() {
             @Override
             public void run() {
-                final BinaryDictionary binaryDictionary = getBinaryDictionary();
-                if (binaryDictionary == null) {
-                    result.set(new DictionaryStats(mLocale, dictName, dictFile,
-                            DictionaryStats.NOT_AN_ENTRY_COUNT,
-                            DictionaryStats.NOT_AN_ENTRY_COUNT));
-                    return;
-                }
-                final int unigramCount = parseEntryCount(
-                        binaryDictionary.getPropertyForGettingStats(
-                                BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
-                // TODO: Get dedicated entry counts for bigram, trigram, and so on.
-                final int ngramCount = parseEntryCount(binaryDictionary.getPropertyForGettingStats(
-                        BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
-                // TODO: Get more information from dictionary.
-                result.set(new DictionaryStats(mLocale, dictName, dictFile, unigramCount,
-                        ngramCount));
+                result.set(new DictionaryStats(mLocale, dictName, dictFile, 0));
             }
         });
         return result.get(null /* defaultValue */, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
diff --git a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
index f7c5f67..62834cd 100644
--- a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
@@ -49,7 +49,7 @@
  */
 public final class CorrectionSettingsFragment extends SubScreenFragment {
     private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false;
-    private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS =
+    private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS =
             DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
             || Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2;
 
@@ -61,8 +61,6 @@
         final Context context = getActivity();
         final PackageManager pm = context.getPackageManager();
 
-        ensureConsistencyOfAutoCorrectionSettings();
-
         final Preference dictionaryLink = findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
         final Intent intent = dictionaryLink.getIntent();
         intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName());
@@ -74,7 +72,7 @@
         final Preference editPersonalDictionary =
                 findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
         final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
-        final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS ? null
+        final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS ? null
                 : pm.resolveActivity(
                         editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY);
         if (ri == null) {
@@ -82,19 +80,6 @@
         }
     }
 
-    @Override
-    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
-        ensureConsistencyOfAutoCorrectionSettings();
-    }
-
-    private void ensureConsistencyOfAutoCorrectionSettings() {
-        final TwoStatePreference autoCorrectionPref = (TwoStatePreference)
-                findPreference(Settings.PREF_AUTO_CORRECTION);
-        if (!autoCorrectionPref.isChecked()) {
-            setPreferenceEnabled(Settings.PREF_BIGRAM_PREDICTIONS, false);
-        }
-    }
-
     private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) {
         final Activity activity = getActivity();
         final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index b98c53a..f5455e3 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -16,10 +16,12 @@
 
 package com.android.inputmethod.latin.settings;
 
+import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
+import android.provider.Settings.Secure;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -68,13 +70,23 @@
 
     @Override
     public boolean onOptionsItemSelected(final MenuItem item) {
+        final Activity activity = getActivity();
+        final int setupStatus = Secure.getInt(
+                activity.getContentResolver(),
+                "user_setup_complete",
+                0 /* default */);
+        if (setupStatus == 0) {
+            // If setup is not complete, it's not safe to launch Help or other activities
+            // because they might go to the Play Store.  See b/19866981.
+            return true;
+        }
         final int itemId = item.getItemId();
         if (itemId == MENU_HELP_AND_FEEDBACK) {
-            FeedbackUtils.showHelpAndFeedbackForm(getActivity());
+            FeedbackUtils.showHelpAndFeedbackForm(activity);
             return true;
         }
         if (itemId == MENU_ABOUT) {
-            final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(getActivity());
+            final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(activity);
             if (aboutIntent != null) {
                 startActivity(aboutIntent);
                 return true;
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
index 3a8d19d..87f2f30 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
@@ -27,8 +27,8 @@
 
 @SmallTest
 public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase {
-    private static final int NUMBER_OF_SUBTYPES = 82;
-    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 50;
+    private static final int NUMBER_OF_SUBTYPES = 81;
+    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 49;
     private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2;
 
     @Override
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
index 613b3bb..a8e8723 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
@@ -16,7 +16,7 @@
 
 package com.android.inputmethod.keyboard.layout.tests;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
 import com.android.inputmethod.keyboard.layout.Qwerty;
@@ -30,7 +30,7 @@
 /*
  * hi_ZZ: Hinglish/qwerty
  */
-@SmallTest
+@Suppress
 public final class TestsHinglish extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("hi", "ZZ");
     private static final LayoutBase LAYOUT = new Qwerty(new HinglishCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index e92831c..e96c934 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -44,10 +44,6 @@
     private static final String TEST_LOCALE = "test";
     private static final String DICTIONARY_ID = "TestBinaryDictionary";
 
-    private static boolean supportsNgram(final int formatVersion) {
-        return formatVersion >= FormatSpec.VERSION403;
-    }
-
     private HashSet<File> mDictFilesToBeDeleted = new HashSet<>();
 
     @Override
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index f2885f5..02cd21c 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -645,22 +645,6 @@
                 mEditText.getText().toString());
     }
 
-    public void testSwitchLanguages() {
-        final String WORD_TO_TYPE_FIRST_PART = "com";
-        final String WORD_TO_TYPE_SECOND_PART = "md";
-        final String EXPECTED_RESULT = "comme";
-        changeLanguage("en");
-        type(WORD_TO_TYPE_FIRST_PART);
-        changeLanguage("fr");
-        runMessages();
-        type(WORD_TO_TYPE_SECOND_PART);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS);
-        runMessages();
-        final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
-        assertEquals("Suggestions updated after switching languages",
-                    EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(1) : null);
-    }
-
     public void testBasicGesture() {
         gesture("this");
         assertEquals("this", mEditText.getText().toString());
@@ -743,18 +727,10 @@
         type(" ");
         typeWordAndPutCursorInside(WORD_TO_TYPE, cursorPos + 1 /* startPos */);
         type(Constants.CODE_DELETE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS);
         ensureComposingSpanPos("delete while in the middle of a word cancels composition", -1, -1);
     }
 
-    public void testAutoCorrectForFrench() {
-        final String STRING_TO_TYPE = "irq ";
-        final String EXPECTED_RESULT = "ir a ";
-        changeLanguage("es");
-        type(STRING_TO_TYPE);
-        assertEquals("simple auto-correct for Spanish", EXPECTED_RESULT,
-                mEditText.getText().toString());
-    }
-
     public void testManualPickThenSeparatorForFrench() {
         final String WORD1_TO_TYPE = "test";
         final String WORD2_TO_TYPE = "!";
@@ -780,13 +756,12 @@
                 mEditText.getText().toString());
     }
 
-    public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() {
+    public void testWordThenSpaceThenPunctuationFromStripTwice() {
         setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, false, true);
 
         final String WORD_TO_TYPE = "test ";
         final String PUNCTUATION_FROM_STRIP = "!";
-        final String EXPECTED_RESULT = "test !!";
-        changeLanguage("fr");
+        final String EXPECTED_RESULT = "test!! ";
         type(WORD_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS);
         runMessages();
@@ -794,14 +769,12 @@
                 mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions());
         pickSuggestionManually(PUNCTUATION_FROM_STRIP);
         pickSuggestionManually(PUNCTUATION_FROM_STRIP);
-        assertEquals("type word then type space then punctuation from strip twice for French",
-                EXPECTED_RESULT, mEditText.getText().toString());
+        assertEquals(EXPECTED_RESULT, mEditText.getText().toString());
     }
 
     public void testWordThenSpaceDisplaysPredictions() {
-        final String WORD_TO_TYPE = "beaujolais ";
-        final String EXPECTED_RESULT = "nouveau";
-        changeLanguage("fr");
+        final String WORD_TO_TYPE = "Barack ";
+        final String EXPECTED_RESULT = "Obama";
         type(WORD_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS);
         runMessages();
@@ -809,22 +782,4 @@
         assertEquals("type word then type space yields predictions for French",
                 EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
     }
-
-    public void testAutoCorrectForGerman() {
-        final String STRING_TO_TYPE = "unf ";
-        final String EXPECTED_RESULT = "und ";
-        changeLanguage("de");
-        type(STRING_TO_TYPE);
-        assertEquals("simple auto-correct for German", EXPECTED_RESULT,
-                mEditText.getText().toString());
-    }
-
-    public void testAutoCorrectWithUmlautForGerman() {
-        final String STRING_TO_TYPE = "ueber ";
-        final String EXPECTED_RESULT = "über ";
-        changeLanguage("de");
-        type(STRING_TO_TYPE);
-        assertEquals("auto-correct with umlaut for German", EXPECTED_RESULT,
-                mEditText.getText().toString());
-    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 0d9b36a..dead53d 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -66,7 +66,8 @@
     protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS = 200;
     // We wait for gesture computation for this delay
     protected static final int DELAY_TO_WAIT_FOR_GESTURE_MILLIS = 200;
-    private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60;
+    // If a dictionary takes longer to load, we could have serious problems.
+    private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 5;
 
     // Type for a test phony dictionary
     private static final String TYPE_TEST = "test";
@@ -106,12 +107,15 @@
                 throw new RuntimeException("Expected one span, found " + spans.length);
             }
         }
+        public SuggestionSpan getSpan() {
+            return (SuggestionSpan) mSpan;
+        }
         public boolean isAutoCorrectionIndicator() {
             return (mSpan instanceof SuggestionSpan) &&
-                    0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & ((SuggestionSpan)mSpan).getFlags());
+                    0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & getSpan().getFlags());
         }
         public String[] getSuggestions() {
-            return ((SuggestionSpan)mSpan).getSuggestions();
+            return getSpan().getSuggestions();
         }
     }
 
@@ -152,8 +156,6 @@
         super(LatinIMEForTests.class);
     }
 
-    // TODO: Isn't there a way to make this generic somehow? We can take a <T> and return a <T>
-    // but we'd have to dispatch types on editor.put...() functions
     protected boolean setBooleanPreference(final String key, final boolean value,
             final boolean defaultValue) {
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
diff --git a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java
index 2272d6b..e7c48da 100644
--- a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java
+++ b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java
@@ -53,14 +53,8 @@
         sleep(1000);
 
         final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class);
-        // If no span, the following will crash
-        final String[] suggestions = span.getSuggestions();
-        // For this test we consider "годп" should yield at least 2 suggestions (at this moment
-        // it yields 5).
-        assertTrue(suggestions.length >= 2);
-        // We also assume the top suggestion should be "года", which is the top word in the
-        // Russian dictionary.
-        assertEquals("", "года", suggestions[0]);
+        // We don't ship with Russian LM
+        assertNull(span.getSpan());
     }
 
     public void testSpellcheckWithPeriods() {