diff --git a/java/src/com/android/inputmethod/latin/makedict/Word.java b/java/src/com/android/inputmethod/latin/makedict/Word.java
index 776b2aa..4e0ab10 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Word.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Word.java
@@ -80,6 +80,7 @@
         if (!(o instanceof Word)) return false;
         Word w = (Word)o;
         return mFrequency == w.mFrequency && mWord.equals(w.mWord)
+                && mIsShortcutOnly == w.mIsShortcutOnly
                 && mShortcutTargets.equals(w.mShortcutTargets)
                 && mBigrams.equals(w.mBigrams);
     }
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
new file mode 100644
index 0000000..81f744d
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 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.keyboard.Keyboard;
+
+public class BlueUnderlineTests extends InputTestsBase {
+
+    public void testBlueUnderline() {
+        final String STRING_TO_TYPE = "tgis";
+        final int EXPECTED_SPAN_START = 0;
+        final int EXPECTED_SPAN_END = 4;
+        type(STRING_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        final Span span = new Span(mTextView.getText());
+        assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart);
+        assertEquals("show blue underline, span end", EXPECTED_SPAN_END, span.mEnd);
+        assertEquals("show blue underline, span color", true, span.isAutoCorrectionIndicator());
+    }
+
+    public void testBlueUnderlineDisappears() {
+        final String STRING_1_TO_TYPE = "tgis";
+        final String STRING_2_TO_TYPE = "q";
+        final int EXPECTED_SPAN_START = 0;
+        final int EXPECTED_SPAN_END = 5;
+        type(STRING_1_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        type(STRING_2_TO_TYPE);
+        // We haven't have time to look into the dictionary yet, so the line should still be
+        // blue to avoid any flicker.
+        final Span spanBefore = new Span(mTextView.getText());
+        assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
+        assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
+        assertEquals("extend blue underline, span color", true,
+                spanBefore.isAutoCorrectionIndicator());
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
+        final Span spanAfter = new Span(mTextView.getText());
+        assertNull("hide blue underline", spanAfter.mSpan);
+    }
+
+    public void testBlueUnderlineOnBackspace() {
+        final String STRING_TO_TYPE = "tgis";
+        final int EXPECTED_SPAN_START = 0;
+        final int EXPECTED_SPAN_END = 4;
+        type(STRING_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        type(Keyboard.CODE_SPACE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        type(Keyboard.CODE_DELETE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        type(Keyboard.CODE_DELETE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        final Span span = new Span(mTextView.getText());
+        assertEquals("show blue underline after backspace, span start",
+                EXPECTED_SPAN_START, span.mStart);
+        assertEquals("show blue underline after backspace, span end",
+                EXPECTED_SPAN_END, span.mEnd);
+        assertEquals("show blue underline after backspace, span color", true,
+                span.isAutoCorrectionIndicator());
+    }
+
+    public void testBlueUnderlineDisappearsWhenCursorMoved() {
+        final String STRING_TO_TYPE = "tgis";
+        final int NEW_CURSOR_POSITION = 0;
+        type(STRING_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        // Simulate the onUpdateSelection() event
+        mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
+        runMessages();
+        // Here the blue underline has been set. testBlueUnderline() is testing for this already,
+        // so let's not test it here again.
+        // Now simulate the user moving the cursor.
+        mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
+        mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        final Span span = new Span(mTextView.getText());
+        assertNull("blue underline removed when cursor is moved", span.mSpan);
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java b/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java
new file mode 100644
index 0000000..5db120d
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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.keyboard.Keyboard;
+
+public class InputLogicFrenchTests extends InputTestsBase {
+
+    public void testAutoCorrectForFrench() {
+        final String STRING_TO_TYPE = "irq ";
+        final String EXPECTED_RESULT = "ira ";
+        changeLanguage("fr");
+        type(STRING_TO_TYPE);
+        assertEquals("simple auto-correct for French", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testManualPickThenSeparatorForFrench() {
+        final String WORD1_TO_TYPE = "test";
+        final String WORD2_TO_TYPE = "!";
+        final String EXPECTED_RESULT = "test !";
+        changeLanguage("fr");
+        type(WORD1_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+        type(WORD2_TO_TYPE);
+        assertEquals("manual pick then separator for French", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() {
+        final String WORD_TO_TYPE = "test ";
+        final String PUNCTUATION_FROM_STRIP = "!";
+        final String EXPECTED_RESULT = "test !!";
+        changeLanguage("fr");
+        type(WORD_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        assertTrue("type word then type space should display punctuation strip",
+                mLatinIME.isShowingPunctuationList());
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        assertEquals("type word then type space then punctuation from strip twice for French",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 19e1c3d..11eb6ab 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -16,194 +16,9 @@
 
 package com.android.inputmethod.latin;
 
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.preference.PreferenceManager;
-import android.test.ServiceTestCase;
-import android.text.InputType;
-import android.text.SpannableStringBuilder;
-import android.text.style.SuggestionSpan;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService; // for proximity info
-import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
 
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class InputLogicTests extends ServiceTestCase<LatinIME> {
-
-    private static final String PREF_DEBUG_MODE = "debug_mode";
-
-    private LatinIME mLatinIME;
-    private Keyboard mKeyboard;
-    private TextView mTextView;
-    private InputConnection mInputConnection;
-
-    public InputLogicTests() {
-        super(LatinIME.class);
-    }
-
-    // returns the previous setting value
-    private boolean setDebugMode(final boolean mode) {
-        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
-        final boolean previousDebugSetting = prefs.getBoolean(PREF_DEBUG_MODE, false);
-        final SharedPreferences.Editor editor = prefs.edit();
-        editor.putBoolean(PREF_DEBUG_MODE, true);
-        editor.commit();
-        return previousDebugSetting;
-    }
-
-    @Override
-    protected void setUp() {
-        try {
-            super.setUp();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        mTextView = new TextView(getContext());
-        mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
-        mTextView.setEnabled(true);
-        setupService();
-        mLatinIME = getService();
-        final boolean previousDebugSetting = setDebugMode(true);
-        mLatinIME.onCreate();
-        setDebugMode(previousDebugSetting);
-        final EditorInfo ei = new EditorInfo();
-        ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
-        final InputConnection ic = mTextView.onCreateInputConnection(ei);
-        ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
-        final LayoutInflater inflater =
-                (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        final ViewGroup vg = new FrameLayout(getContext());
-        final View inputView = inflater.inflate(R.layout.input_view, vg);
-        mLatinIME.setInputView(inputView);
-        mLatinIME.onBindInput();
-        mLatinIME.onCreateInputView();
-        mLatinIME.onStartInputView(ei, false);
-        mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
-        mInputConnection = ic;
-        mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
-        changeLanguage("en_US");
-    }
-
-    // We need to run the messages added to the handler from LatinIME. The only way to do
-    // that is to call Looper#loop() on the right looper, so we're going to get the looper
-    // object and call #loop() here. The messages in the handler actually run on the UI
-    // thread of the keyboard by design of the handler, so we want to call it synchronously
-    // on the same thread that the tests are running on to mimic the actual environment as
-    // closely as possible.
-    // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method
-    // is called, so we need to do that at the right time so that #loop() returns at some
-    // point and we don't end up in an infinite loop.
-    // After we quit, the looper is still technically ready to process more messages but
-    // the handler will refuse to enqueue any because #quit() has been called and it
-    // explicitly tests for it on message enqueuing, so we'll have to reset it so that
-    // it lets us continue normal operation.
-    private void runMessages() {
-        // Here begins deep magic.
-        final Looper looper = mLatinIME.mHandler.getLooper();
-        mLatinIME.mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    looper.quit();
-                }
-            });
-        // The only way to get out of Looper#loop() is to call #quit() on it (or on its queue).
-        // Once #quit() is called remaining messages are not processed, which is why we post
-        // a message that calls it instead of calling it directly.
-        looper.loop();
-
-        // Once #quit() has been called, the message queue has an "mQuiting" field that prevents
-        // any subsequent post in this queue. However the queue itself is still fully functional!
-        // If we have a way of resetting "queue.mQuiting" then we can continue using it as normal,
-        // coming back to this method to run the messages.
-        MessageQueue queue = looper.getQueue();
-        try {
-            // However there is no way of doing it externally, and mQuiting is private.
-            // So... get out the big guns.
-            java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting");
-            f.setAccessible(true); // What do you mean "private"?
-            f.setBoolean(queue, false);
-        } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    // type(int) and type(String): helper methods to send a code point resp. a string to LatinIME.
-    private void type(final int codePoint) {
-        // onPressKey and onReleaseKey are explicitly deactivated here, but they do happen in the
-        // code (although multitouch/slide input and other factors make the sequencing complicated).
-        // They are supposed to be entirely deconnected from the input logic from LatinIME point of
-        // view and only delegates to the parts of the code that care. So we don't include them here
-        // to keep these tests as pinpoint as possible and avoid bringing it too many dependencies,
-        // but keep them in mind if something breaks. Commenting them out as is should work.
-        //mLatinIME.onPressKey(codePoint);
-        for (final Key key : mKeyboard.mKeys) {
-            if (key.mCode == codePoint) {
-                final int x = key.mX + key.mWidth / 2;
-                final int y = key.mY + key.mHeight / 2;
-                mLatinIME.onCodeInput(codePoint, x, y);
-                return;
-            }
-        }
-        mLatinIME.onCodeInput(codePoint,
-                KeyboardActionListener.SPELL_CHECKER_COORDINATE,
-                KeyboardActionListener.SPELL_CHECKER_COORDINATE);
-        //mLatinIME.onReleaseKey(codePoint, false);
-    }
-
-    private void type(final String stringToType) {
-        for (int i = 0; i < stringToType.length(); i = stringToType.offsetByCodePoints(i, 1)) {
-            type(stringToType.codePointAt(i));
-        }
-    }
-
-    private void waitForDictionaryToBeLoaded() {
-        int remainingAttempts = 10;
-        while (remainingAttempts > 0 && !mLatinIME.mSuggest.hasMainDictionary()) {
-            try {
-                Thread.sleep(200);
-            } catch (InterruptedException e) {
-                // Don't do much
-            } finally {
-                --remainingAttempts;
-            }
-        }
-        if (!mLatinIME.mSuggest.hasMainDictionary()) {
-            throw new RuntimeException("Can't initialize the main dictionary");
-        }
-    }
-
-    private void changeLanguage(final String locale) {
-        SubtypeSwitcher.getInstance().updateSubtype(
-                new ArbitrarySubtype(locale, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE));
-        waitForDictionaryToBeLoaded();
-    }
-
-
-    // Helper to avoid writing the try{}catch block each time
-    private static void sleep(final int milliseconds) {
-        try {
-            Thread.sleep(milliseconds);
-        } catch (InterruptedException e) {}
-    }
+public class InputLogicTests extends InputTestsBase {
 
     public void testTypeWord() {
         final String WORD_TO_TYPE = "abcd";
@@ -294,15 +109,6 @@
         assertEquals("simple auto-correct", EXPECTED_RESULT, mTextView.getText().toString());
     }
 
-    public void testAutoCorrectForFrench() {
-        final String STRING_TO_TYPE = "irq ";
-        final String EXPECTED_RESULT = "ira ";
-        changeLanguage("fr");
-        type(STRING_TO_TYPE);
-        assertEquals("simple auto-correct for French", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
     public void testAutoCorrectWithPeriod() {
         final String STRING_TO_TYPE = "tgis.";
         final String EXPECTED_RESULT = "this.";
@@ -390,71 +196,6 @@
         assertEquals("manual pick then separator", EXPECTED_RESULT, mTextView.getText().toString());
     }
 
-    public void testWordThenSpaceThenPunctuationFromStripTwice() {
-        final String WORD_TO_TYPE = "this ";
-        final String PUNCTUATION_FROM_STRIP = "!";
-        final String EXPECTED_RESULT = "this!! ";
-        type(WORD_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        assertTrue("type word then type space should display punctuation strip",
-                mLatinIME.isShowingPunctuationList());
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        assertEquals("type word then type space then punctuation from strip twice", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
-    public void testManualPickThenSeparatorForFrench() {
-        final String WORD1_TO_TYPE = "test";
-        final String WORD2_TO_TYPE = "!";
-        final String EXPECTED_RESULT = "test !";
-        changeLanguage("fr");
-        type(WORD1_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
-        type(WORD2_TO_TYPE);
-        assertEquals("manual pick then separator for French", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
-    public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() {
-        final String WORD_TO_TYPE = "test ";
-        final String PUNCTUATION_FROM_STRIP = "!";
-        final String EXPECTED_RESULT = "test !!";
-        changeLanguage("fr");
-        type(WORD_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        assertTrue("type word then type space should display punctuation strip",
-                mLatinIME.isShowingPunctuationList());
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        assertEquals("type word then type space then punctuation from strip twice for French",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testWordThenSpaceThenPunctuationFromKeyboardTwice() {
-        final String WORD_TO_TYPE = "this !!";
-        final String EXPECTED_RESULT = "this !!";
-        type(WORD_TO_TYPE);
-        assertEquals("manual pick then space then punctuation from keyboard twice", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
-    public void testManualPickThenPunctuationFromStripTwiceThenType() {
-        final String WORD1_TO_TYPE = "this";
-        final String WORD2_TO_TYPE = "is";
-        final String PUNCTUATION_FROM_STRIP = "!";
-        final String EXPECTED_RESULT = "this!! is";
-        type(WORD1_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
-        type(WORD2_TO_TYPE);
-        assertEquals("pick word then pick punctuation twice then type", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
     public void testManualPickThenSpaceThenType() {
         final String WORD1_TO_TYPE = "this";
         final String WORD2_TO_TYPE = " is";
@@ -480,17 +221,6 @@
                 mTextView.getText().toString());
     }
 
-    public void testManualPickThenManualPickWithPunctAtStart() {
-        final String WORD1_TO_TYPE = "this";
-        final String WORD2_TO_PICK = "!is";
-        final String EXPECTED_RESULT = "this!is";
-        type(WORD1_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
-        mLatinIME.pickSuggestionManually(1, WORD2_TO_PICK);
-        assertEquals("manual pick then manual pick a word with punct at start", EXPECTED_RESULT,
-                mTextView.getText().toString());
-    }
-
     public void testDeleteWholeComposingWord() {
         final String WORD_TO_TYPE = "this";
         type(WORD_TO_TYPE);
@@ -499,197 +229,5 @@
         }
         assertEquals("delete whole composing word", "", mTextView.getText().toString());
     }
-
-    public void testManuallyPickedWordThenColon() {
-        final String WORD_TO_TYPE = "this";
-        final String PUNCTUATION = ":";
-        final String EXPECTED_RESULT = "this:";
-        type(WORD_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
-        type(PUNCTUATION);
-        assertEquals("manually pick word then colon",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testManuallyPickedWordThenOpenParen() {
-        final String WORD_TO_TYPE = "this";
-        final String PUNCTUATION = "(";
-        final String EXPECTED_RESULT = "this (";
-        type(WORD_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
-        type(PUNCTUATION);
-        assertEquals("manually pick word then open paren",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testManuallyPickedWordThenCloseParen() {
-        final String WORD_TO_TYPE = "this";
-        final String PUNCTUATION = ")";
-        final String EXPECTED_RESULT = "this)";
-        type(WORD_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
-        type(PUNCTUATION);
-        assertEquals("manually pick word then close paren",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testManuallyPickedWordThenSmiley() {
-        final String WORD_TO_TYPE = "this";
-        final String SPECIAL_KEY = ":-)";
-        final String EXPECTED_RESULT = "this :-)";
-        type(WORD_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
-        mLatinIME.onTextInput(SPECIAL_KEY);
-        assertEquals("manually pick word then press the smiley key",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testManuallyPickedWordThenDotCom() {
-        final String WORD_TO_TYPE = "this";
-        final String SPECIAL_KEY = ".com";
-        final String EXPECTED_RESULT = "this.com";
-        type(WORD_TO_TYPE);
-        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
-        mLatinIME.onTextInput(SPECIAL_KEY);
-        assertEquals("manually pick word then press the .com key",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testTypeWordTypeDotThenPressDotCom() {
-        final String WORD_TO_TYPE = "this.";
-        final String SPECIAL_KEY = ".com";
-        final String EXPECTED_RESULT = "this.com";
-        type(WORD_TO_TYPE);
-        mLatinIME.onTextInput(SPECIAL_KEY);
-        assertEquals("type word type dot then press the .com key",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testAutoCorrectionWithSingleQuoteInside() {
-        final String WORD_TO_TYPE = "you'f ";
-        final String EXPECTED_RESULT = "you'd ";
-        type(WORD_TO_TYPE);
-        assertEquals("auto-correction with single quote inside",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    public void testAutoCorrectionWithSingleQuotesAround() {
-        final String WORD_TO_TYPE = "'tgis' ";
-        final String EXPECTED_RESULT = "'this' ";
-        type(WORD_TO_TYPE);
-        assertEquals("auto-correction with single quotes around",
-                EXPECTED_RESULT, mTextView.getText().toString());
-    }
-
-    // A helper class to ease span tests
-    private static class Span {
-        final SpannableStringBuilder mInputText;
-        final SuggestionSpan mSpan;
-        final int mStart;
-        final int mEnd;
-        // The supplied CharSequence should be an instance of SpannableStringBuilder,
-        // and it should contain exactly zero or one SuggestionSpan. Otherwise, an exception
-        // is thrown.
-        public Span(final CharSequence inputText) {
-            mInputText = (SpannableStringBuilder)inputText;
-            final SuggestionSpan[] spans =
-                    mInputText.getSpans(0, mInputText.length(), SuggestionSpan.class);
-            if (0 == spans.length) {
-                mSpan = null;
-                mStart = -1;
-                mEnd = -1;
-            } else if (1 == spans.length) {
-                mSpan = spans[0];
-                mStart = mInputText.getSpanStart(mSpan);
-                mEnd = mInputText.getSpanEnd(mSpan);
-            } else {
-                throw new RuntimeException("Expected one SuggestionSpan, found " + spans.length);
-            }
-        }
-        public boolean isAutoCorrectionIndicator() {
-            return 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & mSpan.getFlags());
-        }
-    }
-
-    static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200; // The message is posted with a 100 ms delay
-    public void testBlueUnderline() {
-        final String STRING_TO_TYPE = "tgis";
-        final int EXPECTED_SPAN_START = 0;
-        final int EXPECTED_SPAN_END = 4;
-        type(STRING_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        final Span span = new Span(mTextView.getText());
-        assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart);
-        assertEquals("show blue underline, span end", EXPECTED_SPAN_END, span.mEnd);
-        assertEquals("show blue underline, span color", true, span.isAutoCorrectionIndicator());
-    }
-
-    public void testBlueUnderlineDisappears() {
-        final String STRING_1_TO_TYPE = "tgis";
-        final String STRING_2_TO_TYPE = "q";
-        final int EXPECTED_SPAN_START = 0;
-        final int EXPECTED_SPAN_END = 5;
-        type(STRING_1_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        type(STRING_2_TO_TYPE);
-        // We haven't have time to look into the dictionary yet, so the line should still be
-        // blue to avoid any flicker.
-        final Span spanBefore = new Span(mTextView.getText());
-        assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
-        assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
-        assertEquals("extend blue underline, span color", true,
-                spanBefore.isAutoCorrectionIndicator());
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
-        final Span spanAfter = new Span(mTextView.getText());
-        assertNull("hide blue underline", spanAfter.mSpan);
-    }
-
-    public void testBlueUnderlineOnBackspace() {
-        final String STRING_TO_TYPE = "tgis";
-        final int EXPECTED_SPAN_START = 0;
-        final int EXPECTED_SPAN_END = 4;
-        type(STRING_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        type(Keyboard.CODE_SPACE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        type(Keyboard.CODE_DELETE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        type(Keyboard.CODE_DELETE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        final Span span = new Span(mTextView.getText());
-        assertEquals("show blue underline after backspace, span start",
-                EXPECTED_SPAN_START, span.mStart);
-        assertEquals("show blue underline after backspace, span end",
-                EXPECTED_SPAN_END, span.mEnd);
-        assertEquals("show blue underline after backspace, span color", true,
-                span.isAutoCorrectionIndicator());
-    }
-
-    public void testBlueUnderlineDisappearsWhenCursorMoved() {
-        final String STRING_TO_TYPE = "tgis";
-        final int NEW_CURSOR_POSITION = 0;
-        type(STRING_TO_TYPE);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        // Simulate the onUpdateSelection() event
-        mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
-        runMessages();
-        // Here the blue underline has been set. testBlueUnderline() is testing for this already,
-        // so let's not test it here again.
-        // Now simulate the user moving the cursor.
-        mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
-        mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
-        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
-        runMessages();
-        final Span span = new Span(mTextView.getText());
-        assertNull("blue underline removed when cursor is moved", span.mSpan);
-    }
     // TODO: Add some tests for non-BMP characters
 }
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
new file mode 100644
index 0000000..2c63993
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2012 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.content.SharedPreferences;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.preference.PreferenceManager;
+import android.test.ServiceTestCase;
+import android.text.InputType;
+import android.text.SpannableStringBuilder;
+import android.text.style.SuggestionSpan;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class InputTestsBase extends ServiceTestCase<LatinIME> {
+
+    private static final String PREF_DEBUG_MODE = "debug_mode";
+
+    // The message that sets the underline is posted with a 100 ms delay
+    protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200;
+
+    protected LatinIME mLatinIME;
+    protected Keyboard mKeyboard;
+    protected TextView mTextView;
+    protected InputConnection mInputConnection;
+
+    // A helper class to ease span tests
+    public static class Span {
+        final SpannableStringBuilder mInputText;
+        final SuggestionSpan mSpan;
+        final int mStart;
+        final int mEnd;
+        // The supplied CharSequence should be an instance of SpannableStringBuilder,
+        // and it should contain exactly zero or one SuggestionSpan. Otherwise, an exception
+        // is thrown.
+        public Span(final CharSequence inputText) {
+            mInputText = (SpannableStringBuilder)inputText;
+            final SuggestionSpan[] spans =
+                    mInputText.getSpans(0, mInputText.length(), SuggestionSpan.class);
+            if (0 == spans.length) {
+                mSpan = null;
+                mStart = -1;
+                mEnd = -1;
+            } else if (1 == spans.length) {
+                mSpan = spans[0];
+                mStart = mInputText.getSpanStart(mSpan);
+                mEnd = mInputText.getSpanEnd(mSpan);
+            } else {
+                throw new RuntimeException("Expected one SuggestionSpan, found " + spans.length);
+            }
+        }
+        public boolean isAutoCorrectionIndicator() {
+            return 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & mSpan.getFlags());
+        }
+    }
+
+    public InputTestsBase() {
+        super(LatinIME.class);
+    }
+
+    // returns the previous setting value
+    protected boolean setDebugMode(final boolean mode) {
+        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
+        final boolean previousDebugSetting = prefs.getBoolean(PREF_DEBUG_MODE, false);
+        final SharedPreferences.Editor editor = prefs.edit();
+        editor.putBoolean(PREF_DEBUG_MODE, true);
+        editor.commit();
+        return previousDebugSetting;
+    }
+
+    @Override
+    protected void setUp() {
+        try {
+            super.setUp();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        mTextView = new TextView(getContext());
+        mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
+        mTextView.setEnabled(true);
+        setupService();
+        mLatinIME = getService();
+        final boolean previousDebugSetting = setDebugMode(true);
+        mLatinIME.onCreate();
+        setDebugMode(previousDebugSetting);
+        final EditorInfo ei = new EditorInfo();
+        ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
+        final InputConnection ic = mTextView.onCreateInputConnection(ei);
+        ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
+        final LayoutInflater inflater =
+                (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        final ViewGroup vg = new FrameLayout(getContext());
+        final View inputView = inflater.inflate(R.layout.input_view, vg);
+        mLatinIME.setInputView(inputView);
+        mLatinIME.onBindInput();
+        mLatinIME.onCreateInputView();
+        mLatinIME.onStartInputView(ei, false);
+        mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
+        mInputConnection = ic;
+        mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
+        changeLanguage("en_US");
+    }
+
+    // We need to run the messages added to the handler from LatinIME. The only way to do
+    // that is to call Looper#loop() on the right looper, so we're going to get the looper
+    // object and call #loop() here. The messages in the handler actually run on the UI
+    // thread of the keyboard by design of the handler, so we want to call it synchronously
+    // on the same thread that the tests are running on to mimic the actual environment as
+    // closely as possible.
+    // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method
+    // is called, so we need to do that at the right time so that #loop() returns at some
+    // point and we don't end up in an infinite loop.
+    // After we quit, the looper is still technically ready to process more messages but
+    // the handler will refuse to enqueue any because #quit() has been called and it
+    // explicitly tests for it on message enqueuing, so we'll have to reset it so that
+    // it lets us continue normal operation.
+    protected void runMessages() {
+        // Here begins deep magic.
+        final Looper looper = mLatinIME.mHandler.getLooper();
+        mLatinIME.mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    looper.quit();
+                }
+            });
+        // The only way to get out of Looper#loop() is to call #quit() on it (or on its queue).
+        // Once #quit() is called remaining messages are not processed, which is why we post
+        // a message that calls it instead of calling it directly.
+        looper.loop();
+
+        // Once #quit() has been called, the message queue has an "mQuiting" field that prevents
+        // any subsequent post in this queue. However the queue itself is still fully functional!
+        // If we have a way of resetting "queue.mQuiting" then we can continue using it as normal,
+        // coming back to this method to run the messages.
+        MessageQueue queue = looper.getQueue();
+        try {
+            // However there is no way of doing it externally, and mQuiting is private.
+            // So... get out the big guns.
+            java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting");
+            f.setAccessible(true); // What do you mean "private"?
+            f.setBoolean(queue, false);
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // type(int) and type(String): helper methods to send a code point resp. a string to LatinIME.
+    protected void type(final int codePoint) {
+        // onPressKey and onReleaseKey are explicitly deactivated here, but they do happen in the
+        // code (although multitouch/slide input and other factors make the sequencing complicated).
+        // They are supposed to be entirely deconnected from the input logic from LatinIME point of
+        // view and only delegates to the parts of the code that care. So we don't include them here
+        // to keep these tests as pinpoint as possible and avoid bringing it too many dependencies,
+        // but keep them in mind if something breaks. Commenting them out as is should work.
+        //mLatinIME.onPressKey(codePoint);
+        for (final Key key : mKeyboard.mKeys) {
+            if (key.mCode == codePoint) {
+                final int x = key.mX + key.mWidth / 2;
+                final int y = key.mY + key.mHeight / 2;
+                mLatinIME.onCodeInput(codePoint, x, y);
+                return;
+            }
+        }
+        mLatinIME.onCodeInput(codePoint,
+                KeyboardActionListener.SPELL_CHECKER_COORDINATE,
+                KeyboardActionListener.SPELL_CHECKER_COORDINATE);
+        //mLatinIME.onReleaseKey(codePoint, false);
+    }
+
+    protected void type(final String stringToType) {
+        for (int i = 0; i < stringToType.length(); i = stringToType.offsetByCodePoints(i, 1)) {
+            type(stringToType.codePointAt(i));
+        }
+    }
+
+    protected void waitForDictionaryToBeLoaded() {
+        int remainingAttempts = 10;
+        while (remainingAttempts > 0 && !mLatinIME.mSuggest.hasMainDictionary()) {
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+                // Don't do much
+            } finally {
+                --remainingAttempts;
+            }
+        }
+        if (!mLatinIME.mSuggest.hasMainDictionary()) {
+            throw new RuntimeException("Can't initialize the main dictionary");
+        }
+    }
+
+    protected void changeLanguage(final String locale) {
+        SubtypeSwitcher.getInstance().updateSubtype(
+                new ArbitrarySubtype(locale, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE));
+        waitForDictionaryToBeLoaded();
+    }
+
+
+    // Helper to avoid writing the try{}catch block each time
+    protected static void sleep(final int milliseconds) {
+        try {
+            Thread.sleep(milliseconds);
+        } catch (InterruptedException e) {}
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/PunctuationTests.java b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
new file mode 100644
index 0000000..cc549bc
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 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.keyboard.Keyboard;
+
+public class PunctuationTests extends InputTestsBase {
+
+    public void testWordThenSpaceThenPunctuationFromStripTwice() {
+        final String WORD_TO_TYPE = "this ";
+        final String PUNCTUATION_FROM_STRIP = "!";
+        final String EXPECTED_RESULT = "this!! ";
+        type(WORD_TO_TYPE);
+        sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+        runMessages();
+        assertTrue("type word then type space should display punctuation strip",
+                mLatinIME.isShowingPunctuationList());
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        assertEquals("type word then type space then punctuation from strip twice", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testWordThenSpaceThenPunctuationFromKeyboardTwice() {
+        final String WORD_TO_TYPE = "this !!";
+        final String EXPECTED_RESULT = "this !!";
+        type(WORD_TO_TYPE);
+        assertEquals("manual pick then space then punctuation from keyboard twice", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testManualPickThenPunctuationFromStripTwiceThenType() {
+        final String WORD1_TO_TYPE = "this";
+        final String WORD2_TO_TYPE = "is";
+        final String PUNCTUATION_FROM_STRIP = "!";
+        final String EXPECTED_RESULT = "this!! is";
+        type(WORD1_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+        type(WORD2_TO_TYPE);
+        assertEquals("pick word then pick punctuation twice then type", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testManualPickThenManualPickWithPunctAtStart() {
+        final String WORD1_TO_TYPE = "this";
+        final String WORD2_TO_PICK = "!is";
+        final String EXPECTED_RESULT = "this!is";
+        type(WORD1_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+        mLatinIME.pickSuggestionManually(1, WORD2_TO_PICK);
+        assertEquals("manual pick then manual pick a word with punct at start", EXPECTED_RESULT,
+                mTextView.getText().toString());
+    }
+
+    public void testManuallyPickedWordThenColon() {
+        final String WORD_TO_TYPE = "this";
+        final String PUNCTUATION = ":";
+        final String EXPECTED_RESULT = "this:";
+        type(WORD_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+        type(PUNCTUATION);
+        assertEquals("manually pick word then colon",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testManuallyPickedWordThenOpenParen() {
+        final String WORD_TO_TYPE = "this";
+        final String PUNCTUATION = "(";
+        final String EXPECTED_RESULT = "this (";
+        type(WORD_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+        type(PUNCTUATION);
+        assertEquals("manually pick word then open paren",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testManuallyPickedWordThenCloseParen() {
+        final String WORD_TO_TYPE = "this";
+        final String PUNCTUATION = ")";
+        final String EXPECTED_RESULT = "this)";
+        type(WORD_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+        type(PUNCTUATION);
+        assertEquals("manually pick word then close paren",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testManuallyPickedWordThenSmiley() {
+        final String WORD_TO_TYPE = "this";
+        final String SPECIAL_KEY = ":-)";
+        final String EXPECTED_RESULT = "this :-)";
+        type(WORD_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+        mLatinIME.onTextInput(SPECIAL_KEY);
+        assertEquals("manually pick word then press the smiley key",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testManuallyPickedWordThenDotCom() {
+        final String WORD_TO_TYPE = "this";
+        final String SPECIAL_KEY = ".com";
+        final String EXPECTED_RESULT = "this.com";
+        type(WORD_TO_TYPE);
+        mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+        mLatinIME.onTextInput(SPECIAL_KEY);
+        assertEquals("manually pick word then press the .com key",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testTypeWordTypeDotThenPressDotCom() {
+        final String WORD_TO_TYPE = "this.";
+        final String SPECIAL_KEY = ".com";
+        final String EXPECTED_RESULT = "this.com";
+        type(WORD_TO_TYPE);
+        mLatinIME.onTextInput(SPECIAL_KEY);
+        assertEquals("type word type dot then press the .com key",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testAutoCorrectionWithSingleQuoteInside() {
+        final String WORD_TO_TYPE = "you'f ";
+        final String EXPECTED_RESULT = "you'd ";
+        type(WORD_TO_TYPE);
+        assertEquals("auto-correction with single quote inside",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
+    public void testAutoCorrectionWithSingleQuotesAround() {
+        final String WORD_TO_TYPE = "'tgis' ";
+        final String EXPECTED_RESULT = "'this' ";
+        type(WORD_TO_TYPE);
+        assertEquals("auto-correction with single quotes around",
+                EXPECTED_RESULT, mTextView.getText().toString());
+    }
+}
