diff --git a/tests/res/raw/test.dict b/tests/res/raw/test.dict
deleted file mode 100644
index 453fc9f..0000000
--- a/tests/res/raw/test.dict
+++ /dev/null
Binary files differ
diff --git a/tests/src/com/android/inputmethod/latin/SuggestHelper.java b/tests/src/com/android/inputmethod/latin/SuggestHelper.java
deleted file mode 100644
index 0c023bd..0000000
--- a/tests/src/com/android/inputmethod/latin/SuggestHelper.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.inputmethod.latin;
-
-import android.content.Context;
-import android.text.TextUtils;
-
-import com.android.inputmethod.keyboard.KeyDetector;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.keyboard.KeyboardSet;
-
-import java.io.File;
-import java.util.Locale;
-
-public class SuggestHelper {
-    protected final Suggest mSuggest;
-    protected int mCorrectionMode;
-    protected final Keyboard mKeyboard;
-    private final KeyDetector mKeyDetector;
-
-    public SuggestHelper(Context context, int dictionaryId, KeyboardSet keyboardSet) {
-        // Use null as the locale for Suggest so as to force it to use the internal dictionary
-        // (and not try to find a dictionary provider for a specified locale)
-        this(new Suggest(context, dictionaryId, null), keyboardSet);
-    }
-
-    protected SuggestHelper(final Context context, final File dictionaryPath,
-            final long startOffset, final long length, final KeyboardSet keyboardSet,
-            final Locale locale) {
-        this(new Suggest(context, dictionaryPath, startOffset, length, null, locale), keyboardSet);
-    }
-
-    private SuggestHelper(final Suggest suggest, final KeyboardSet keyboardSet) {
-        mSuggest = suggest;
-        mKeyboard = keyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
-        mKeyDetector = new KeyDetector(0);
-
-        setCorrectionMode(Suggest.CORRECTION_FULL);
-        mKeyDetector.setKeyboard(mKeyboard, 0, 0);
-        mKeyDetector.setProximityCorrectionEnabled(true);
-        mKeyDetector.setProximityThreshold(mKeyboard.mMostCommonKeyWidth);
-    }
-
-    public void setCorrectionMode(int correctionMode) {
-        mCorrectionMode = correctionMode;
-    }
-
-    public boolean hasMainDictionary() {
-        return mSuggest.hasMainDictionary();
-    }
-
-    protected WordComposer createWordComposer(CharSequence s) {
-        WordComposer word = new WordComposer();
-        word.setComposingWord(s, mKeyboard, mKeyDetector);
-        return word;
-    }
-
-    public boolean isValidWord(CharSequence typed) {
-        return AutoCorrection.isValidWord(mSuggest.getUnigramDictionaries(),
-                typed, false);
-    }
-
-    // TODO: This may be slow, but is OK for test so far.
-    public SuggestedWords getSuggestions(CharSequence typed) {
-        return mSuggest.getSuggestions(createWordComposer(typed), null,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-    }
-
-    public CharSequence getFirstSuggestion(CharSequence typed) {
-        WordComposer word = createWordComposer(typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        // Note that suggestions.getWord(0) is the word user typed.
-        return suggestions.size() > 1 ? suggestions.getWord(1) : null;
-    }
-
-    public CharSequence getAutoCorrection(CharSequence typed) {
-        WordComposer word = createWordComposer(typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        // Note that suggestions.getWord(0) is the word user typed.
-        return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
-                ? suggestions.getWord(1) : null;
-    }
-
-    public int getSuggestIndex(CharSequence typed, CharSequence expected) {
-        WordComposer word = createWordComposer(typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        // Note that suggestions.getWord(0) is the word user typed.
-        for (int i = 1; i < suggestions.size(); i++) {
-            if (TextUtils.equals(suggestions.getWord(i), expected))
-                return i;
-        }
-        return -1;
-    }
-
-    private void getBigramSuggestions(CharSequence previous, CharSequence typed) {
-        if (!TextUtils.isEmpty(previous) && (typed.length() > 1)) {
-            WordComposer firstChar = createWordComposer(Character.toString(typed.charAt(0)));
-            mSuggest.getSuggestions(firstChar, previous, mKeyboard.getProximityInfo(),
-                    mCorrectionMode);
-        }
-    }
-
-    public CharSequence getBigramFirstSuggestion(CharSequence previous, CharSequence typed) {
-        WordComposer word = createWordComposer(typed);
-        getBigramSuggestions(previous, typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        return suggestions.size() > 1 ? suggestions.getWord(1) : null;
-    }
-
-    public CharSequence getBigramAutoCorrection(CharSequence previous, CharSequence typed) {
-        WordComposer word = createWordComposer(typed);
-        getBigramSuggestions(previous, typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
-                ? suggestions.getWord(1) : null;
-    }
-
-    public int searchBigramSuggestion(CharSequence previous, CharSequence typed,
-            CharSequence expected) {
-        WordComposer word = createWordComposer(typed);
-        getBigramSuggestions(previous, typed);
-        SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
-                mKeyboard.getProximityInfo(), mCorrectionMode);
-        for (int i = 1; i < suggestions.size(); i++) {
-            if (TextUtils.equals(suggestions.getWord(i), expected))
-                return i;
-        }
-        return -1;
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTests.java b/tests/src/com/android/inputmethod/latin/SuggestTests.java
deleted file mode 100644
index e12ae58..0000000
--- a/tests/src/com/android/inputmethod/latin/SuggestTests.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2010,2011 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.
- */
-
-package com.android.inputmethod.latin;
-
-import com.android.inputmethod.latin.tests.R;
-
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Configuration;
-
-import java.util.Locale;
-
-public class SuggestTests extends SuggestTestsBase {
-    private SuggestHelper mHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
-        final Locale locale = Locale.US;
-        mHelper = new SuggestHelper(
-                getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
-                createKeyboardSet(locale, Configuration.ORIENTATION_PORTRAIT), locale);
-        mHelper.setCorrectionMode(Suggest.CORRECTION_FULL_BIGRAM);
-    }
-
-    /************************** Tests ************************/
-
-    /**
-     * Tests for simple completions of one character.
-     */
-    public void testCompletion1char() {
-        suggested("people", mHelper.getFirstSuggestion("peopl"));
-        suggested("about", mHelper.getFirstSuggestion("abou"));
-        suggested("their", mHelper.getFirstSuggestion("thei"));
-    }
-
-    /**
-     * Tests for simple completions of two characters.
-     */
-    public void testCompletion2char() {
-        suggested("people", mHelper.getFirstSuggestion("peop"));
-        suggested("calling", mHelper.getFirstSuggestion("calli"));
-        suggested("business", mHelper.getFirstSuggestion("busine"));
-    }
-
-    /**
-     * Tests for proximity errors.
-     */
-    public void testProximityPositive() {
-        suggested("typed peiple", "people", mHelper.getFirstSuggestion("peiple"));
-        suggested("typed peoole", "people", mHelper.getFirstSuggestion("peoole"));
-        suggested("typed pwpple", "people", mHelper.getFirstSuggestion("pwpple"));
-    }
-
-    /**
-     * Tests for proximity errors - negative, when the error key is not close.
-     */
-    public void testProximityNegative() {
-        notSuggested("about", mHelper.getFirstSuggestion("arout"));
-        notSuggested("are", mHelper.getFirstSuggestion("ire"));
-    }
-
-    /**
-     * Tests for checking if apostrophes are added automatically.
-     */
-    public void testApostropheInsertion() {
-        suggested("I'm", mHelper.getFirstSuggestion("im"));
-        suggested("don't", mHelper.getFirstSuggestion("dont"));
-    }
-
-    /**
-     * Test to make sure apostrophed word is not suggested for an apostrophed word.
-     */
-    public void testApostrophe() {
-        notSuggested("don't", mHelper.getFirstSuggestion("don't"));
-    }
-
-    /**
-     * Tests for suggestion of capitalized version of a word.
-     */
-    public void testCapitalization() {
-        suggested("I'm", mHelper.getFirstSuggestion("i'm"));
-        suggested("Sunday", mHelper.getFirstSuggestion("sunday"));
-        suggested("Sunday", mHelper.getFirstSuggestion("sundat"));
-    }
-
-    /**
-     * Tests to see if more than one completion is provided for certain prefixes.
-     */
-    public void testMultipleCompletions() {
-        isInSuggestions("com: come", mHelper.getSuggestIndex("com", "come"));
-        isInSuggestions("com: company", mHelper.getSuggestIndex("com", "company"));
-        isInSuggestions("th: the", mHelper.getSuggestIndex("th", "the"));
-        isInSuggestions("th: that", mHelper.getSuggestIndex("th", "that"));
-        isInSuggestions("th: this", mHelper.getSuggestIndex("th", "this"));
-        isInSuggestions("th: they", mHelper.getSuggestIndex("th", "they"));
-    }
-
-    /**
-     * Does the suggestion engine recognize zero frequency words as valid words.
-     */
-    public void testZeroFrequencyAccepted() {
-        assertTrue("valid word yikes", mHelper.isValidWord("yikes"));
-        assertFalse("non valid word yike", mHelper.isValidWord("yike"));
-    }
-
-    /**
-     * Tests to make sure that zero frequency words are not suggested as completions.
-     */
-    public void testZeroFrequencySuggestionsNegative() {
-        assertTrue(mHelper.getSuggestIndex("yike", "yikes") < 0);
-        assertTrue(mHelper.getSuggestIndex("what", "whatcha") < 0);
-    }
-
-    /**
-     * Tests to ensure that words with large edit distances are not suggested, in some cases.
-     * Also such word is not considered auto correction, in some cases.
-     */
-    public void testTooLargeEditDistance() {
-        assertTrue(mHelper.getSuggestIndex("sniyr", "about") < 0);
-        // TODO: The following test fails.
-        // notSuggested("the", mHelper.getAutoCorrection("rjw"));
-    }
-
-    /**
-     * Make sure mHelper.isValidWord is case-sensitive.
-     */
-    public void testValidityCaseSensitivity() {
-        assertTrue("valid word Sunday", mHelper.isValidWord("Sunday"));
-        assertFalse("non valid word sunday", mHelper.isValidWord("sunday"));
-    }
-
-    /**
-     * Are accented forms of words suggested as corrections?
-     */
-    public void testAccents() {
-        // ni<LATIN SMALL LETTER N WITH TILDE>o
-        suggested("ni\u00F1o", mHelper.getAutoCorrection("nino"));
-        // ni<LATIN SMALL LETTER N WITH TILDE>o
-        suggested("ni\u00F1o", mHelper.getAutoCorrection("nimo"));
-        // Mar<LATIN SMALL LETTER I WITH ACUTE>a
-        suggested("Mar\u00EDa", mHelper.getAutoCorrection("maria"));
-    }
-
-    /**
-     * Make sure bigrams are showing when first character is typed
-     *  and don't show any when there aren't any
-     */
-    public void testBigramsAtFirstChar() {
-        suggested("bigram: about p[art]",
-                "part", mHelper.getBigramFirstSuggestion("about", "p"));
-        suggested("bigram: I'm a[bout]",
-                "about", mHelper.getBigramFirstSuggestion("I'm", "a"));
-        suggested("bigram: about b[usiness]",
-                "business", mHelper.getBigramFirstSuggestion("about", "b"));
-        isInSuggestions("bigram: about b[eing]",
-                mHelper.searchBigramSuggestion("about", "b", "being"));
-        notSuggested("bigram: about p",
-                "business", mHelper.getBigramFirstSuggestion("about", "p"));
-    }
-
-    /**
-     * Make sure bigrams score affects the original score
-     */
-    public void testBigramsScoreEffect() {
-        suggested("single: page",
-                "page", mHelper.getAutoCorrection("pa"));
-        suggested("bigram: about pa[rt]",
-                "part", mHelper.getBigramAutoCorrection("about", "pa"));
-        // TODO: The following test fails.
-        // suggested("single: said", "said", mHelper.getAutoCorrection("sa"));
-        // TODO: The following test fails due to "transpose correction".
-        // suggested("bigram: from sa[me]",
-        //        "same", mHelper.getBigramAutoCorrection("from", "sa"));
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
deleted file mode 100644
index 73e34ba..0000000
--- a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.inputmethod.latin;
-
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Configuration;
-import android.test.AndroidTestCase;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.view.inputmethod.EditorInfo;
-
-import com.android.inputmethod.keyboard.KeyboardSet;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Locale;
-
-public class SuggestTestsBase extends AndroidTestCase {
-    protected File mTestPackageFile;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestPackageFile = new File(getTestContext().getApplicationInfo().sourceDir);
-    }
-
-    protected KeyboardSet createKeyboardSet(Locale locale, int orientation) {
-        return createKeyboardSet(locale, orientation, false);
-    }
-
-    protected KeyboardSet createKeyboardSet(Locale locale, int orientation,
-            boolean touchPositionCorrectionEnabled) {
-        final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
-        final int width;
-        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            width = Math.max(dm.widthPixels, dm.heightPixels);
-        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-            width = Math.min(dm.widthPixels, dm.heightPixels);
-        } else {
-            fail("Orientation should be ORIENTATION_LANDSCAPE or ORIENTATION_PORTRAIT: "
-                    + "orientation=" + orientation);
-            return null;
-        }
-        final EditorInfo editorInfo = new EditorInfo();
-        editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
-        final KeyboardSet.Builder builder = new KeyboardSet.Builder(getContext(), editorInfo);
-        builder.setScreenGeometry(orientation, width);
-        builder.setSubtype(locale, true, touchPositionCorrectionEnabled);
-        return builder.build();
-    }
-
-    protected InputStream openTestRawResource(int resIdInTest) {
-        return getTestContext().getResources().openRawResource(resIdInTest);
-    }
-
-    protected AssetFileDescriptor openTestRawResourceFd(int resIdInTest) {
-        return getTestContext().getResources().openRawResourceFd(resIdInTest);
-    }
-
-    private static String format(String message, Object expected, Object actual) {
-        return message + " expected:<" + expected + "> but was:<" + actual + ">";
-    }
-
-    protected static void suggested(CharSequence expected, CharSequence actual) {
-        if (!TextUtils.equals(expected, actual))
-            fail(format("assertEquals", expected, actual));
-    }
-
-    protected static void suggested(String message, CharSequence expected, CharSequence actual) {
-        if (!TextUtils.equals(expected, actual))
-            fail(format(message, expected, actual));
-    }
-
-    protected static void notSuggested(CharSequence expected, CharSequence actual) {
-        if (TextUtils.equals(expected, actual))
-            fail(format("assertNotEquals", expected, actual));
-    }
-
-    protected static void notSuggested(String message, CharSequence expected, CharSequence actual) {
-        if (TextUtils.equals(expected, actual))
-            fail(format(message, expected, actual));
-    }
-
-    protected static void isInSuggestions(String message, int position) {
-        assertTrue(message, position >= 0);
-    }
-
-    protected static void isNotInSuggestions(String message, int position) {
-        assertTrue(message, position < 0);
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/UserBigramSuggestHelper.java b/tests/src/com/android/inputmethod/latin/UserBigramSuggestHelper.java
deleted file mode 100644
index 74fadf7..0000000
--- a/tests/src/com/android/inputmethod/latin/UserBigramSuggestHelper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.inputmethod.latin;
-
-import android.content.Context;
-import android.text.TextUtils;
-
-import com.android.inputmethod.keyboard.KeyboardSet;
-
-import java.io.File;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-public class UserBigramSuggestHelper extends SuggestHelper {
-    private final Context mContext;
-    private UserBigramDictionary mUserBigram;
-
-    public UserBigramSuggestHelper(final Context context, final File dictionaryPath,
-            final long startOffset, final long length, final int userBigramMax,
-            final int userBigramDelete, final KeyboardSet keyboardSet, final Locale locale) {
-        super(context, dictionaryPath, startOffset, length, keyboardSet, locale);
-        mContext = context;
-        mUserBigram = new UserBigramDictionary(context, null, locale.toString(),
-                Suggest.DIC_USER);
-        mUserBigram.setDatabaseMax(userBigramMax);
-        mUserBigram.setDatabaseDelete(userBigramDelete);
-        setCorrectionMode(Suggest.CORRECTION_FULL_BIGRAM);
-        mSuggest.setUserBigramDictionary(mUserBigram);
-    }
-
-    public void changeUserBigramLocale(Locale locale) {
-        if (mUserBigram != null) {
-            flushUserBigrams();
-            mUserBigram.close();
-            mUserBigram = new UserBigramDictionary(mContext, null, locale.toString(),
-                    Suggest.DIC_USER);
-            mSuggest.setUserBigramDictionary(mUserBigram);
-        }
-    }
-
-    public int searchUserBigramSuggestion(CharSequence previous, char typed,
-            CharSequence expected) {
-        if (mUserBigram == null) return -1;
-
-        flushUserBigrams();
-        if (!TextUtils.isEmpty(previous) && !TextUtils.isEmpty(Character.toString(typed))) {
-            WordComposer firstChar = createWordComposer(Character.toString(typed));
-            mSuggest.getSuggestions(firstChar, previous, mKeyboard.getProximityInfo(),
-                    mCorrectionMode);
-            boolean reloading = mUserBigram.reloadDictionaryIfRequired();
-            if (reloading) mUserBigram.waitForDictionaryLoading();
-            mUserBigram.getBigrams(firstChar, previous, mSuggest);
-        }
-
-        for (int i = 0; i < mSuggest.mBigramSuggestions.size(); i++) {
-            final CharSequence word = mSuggest.mBigramSuggestions.get(i);
-            if (TextUtils.equals(word, expected))
-                return i;
-        }
-
-        return -1;
-    }
-
-    public void addToUserBigram(String sentence) {
-        StringTokenizer st = new StringTokenizer(sentence);
-        String previous = null;
-        while (st.hasMoreTokens()) {
-            String current = st.nextToken();
-            if (previous != null) {
-                addToUserBigram(new String[] {previous, current});
-            }
-            previous = current;
-        }
-    }
-
-    public void addToUserBigram(String[] pair) {
-        if (mUserBigram != null && pair.length == 2) {
-            mUserBigram.addBigrams(pair[0], pair[1]);
-        }
-    }
-
-    public void flushUserBigrams() {
-        if (mUserBigram != null) {
-            mUserBigram.flushPendingWrites();
-            mUserBigram.waitUntilUpdateDBDone();
-        }
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java b/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java
deleted file mode 100644
index 2b88a7c..0000000
--- a/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010,2011 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.
- */
-
-package com.android.inputmethod.latin;
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Configuration;
-
-import com.android.inputmethod.latin.tests.R;
-
-import java.util.Locale;
-
-public class UserBigramSuggestTests extends SuggestTestsBase {
-    private static final int SUGGESTION_STARTS = 1;
-    private static final int MAX_DATA = 20;
-    private static final int DELETE_DATA = 10;
-
-    private UserBigramSuggestHelper mHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
-        final Locale locale = Locale.US;
-        mHelper = new UserBigramSuggestHelper(
-                getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
-                MAX_DATA, DELETE_DATA,
-                createKeyboardSet(locale, Configuration.ORIENTATION_PORTRAIT), locale);
-    }
-
-    /************************** Tests ************************/
-
-    /**
-     * Test suggestion started at right time
-     */
-    public void testUserBigram() {
-        for (int i = 0; i < SUGGESTION_STARTS; i++) mHelper.addToUserBigram(pair1);
-        for (int i = 0; i < (SUGGESTION_STARTS - 1); i++) mHelper.addToUserBigram(pair2);
-
-        isInSuggestions("bigram", mHelper.searchUserBigramSuggestion("user", 'b', "bigram"));
-        isNotInSuggestions("platform",
-                mHelper.searchUserBigramSuggestion("android", 'p', "platform"));
-    }
-
-    /**
-     * Test loading correct (locale) bigrams
-     */
-    public void testOpenAndClose() {
-        for (int i = 0; i < SUGGESTION_STARTS; i++) mHelper.addToUserBigram(pair1);
-        isInSuggestions("bigram in default locale",
-                mHelper.searchUserBigramSuggestion("user", 'b', "bigram"));
-
-        // change to fr_FR
-        mHelper.changeUserBigramLocale(Locale.FRANCE);
-        for (int i = 0; i < SUGGESTION_STARTS; i++) mHelper.addToUserBigram(pair3);
-        isInSuggestions("france in fr_FR",
-                mHelper.searchUserBigramSuggestion("locale", 'f', "france"));
-        isNotInSuggestions("bigram in fr_FR",
-                mHelper.searchUserBigramSuggestion("user", 'b', "bigram"));
-
-        // change back to en_US
-        mHelper.changeUserBigramLocale(Locale.US);
-        isNotInSuggestions("france in en_US",
-                mHelper.searchUserBigramSuggestion("locale", 'f', "france"));
-        isInSuggestions("bigram in en_US",
-                mHelper.searchUserBigramSuggestion("user", 'b', "bigram"));
-    }
-
-    /**
-     * Test data gets pruned when it is over maximum
-     */
-    public void testPruningData() {
-        for (int i = 0; i < SUGGESTION_STARTS; i++) mHelper.addToUserBigram(sentence0);
-        mHelper.flushUserBigrams();
-        isInSuggestions("world after several sentence 0",
-                mHelper.searchUserBigramSuggestion("Hello", 'w', "world"));
-
-        mHelper.addToUserBigram(sentence1);
-        mHelper.addToUserBigram(sentence2);
-        isInSuggestions("world after sentence 1 and 2",
-                mHelper.searchUserBigramSuggestion("Hello", 'w', "world"));
-
-        // pruning should happen
-        mHelper.addToUserBigram(sentence3);
-        mHelper.addToUserBigram(sentence4);
-
-        // trying to reopen database to check pruning happened in database
-        mHelper.changeUserBigramLocale(Locale.US);
-        isNotInSuggestions("world after sentence 3 and 4",
-                mHelper.searchUserBigramSuggestion("Hello", 'w', "world"));
-    }
-
-    private static final String[] pair1 = {"user", "bigram"};
-    private static final String[] pair2 = {"android","platform"};
-    private static final String[] pair3 = {"locale", "france"};
-    private static final String sentence0 = "Hello world";
-    private static final String sentence1 = "This is a test for user input based bigram";
-    private static final String sentence2 = "It learns phrases that contain both dictionary and "
-        + "nondictionary words";
-    private static final String sentence3 = "This should give better suggestions than the previous "
-        + "version";
-    private static final String sentence4 = "Android stock keyboard is improving";
-}
