diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index 6e55539..3636bbf 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -392,11 +392,11 @@
     /**
      * data object to hold suggestion values
      */
-    class SuggestItem {
-        String title;
-        String url;
-        int type;
-        String extra;
+    public class SuggestItem {
+        public String title;
+        public String url;
+        public int type;
+        public String extra;
 
         public SuggestItem(String text, String u, int t) {
             title = text;
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index 85935a0..1b33084 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -16,6 +16,7 @@
 
 package com.android.browser;
 
+import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
 import com.android.browser.search.SearchEngine;
 
 import android.app.Activity;
@@ -23,10 +24,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
-import android.text.Editable;
 import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -45,8 +43,7 @@
  * tabbed title bar for xlarge screen browser
  */
 public class TitleBarXLarge extends TitleBarBase
-        implements OnClickListener, OnFocusChangeListener,
-    TextWatcher {
+        implements OnClickListener, OnFocusChangeListener, TextChangeWatcher {
 
     private XLargeUi mUi;
 
@@ -136,7 +133,7 @@
         mUrlInput.setController(mUiController);
         mUrlInput.setOnFocusChangeListener(this);
         mUrlInput.setSelectAllOnFocus(true);
-        mUrlInput.addTextChangedListener(this);
+        mUrlInput.addQueryTextWatcher(this);
         setFocusState(false);
     }
 
@@ -372,7 +369,7 @@
     // UrlInput text watcher
 
     @Override
-    public void afterTextChanged(Editable s) {
+    public void onTextChanged(String newText) {
         if (mUrlInput.hasFocus()) {
             // check if input field is empty and adjust voice search state
             updateSearchMode(true);
@@ -381,14 +378,6 @@
         }
     }
 
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
     // voicesearch
 
     @Override
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 2ec2111..362e941 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -18,6 +18,7 @@
 
 import com.android.browser.SuggestionsAdapter.CompletionListener;
 import com.android.browser.SuggestionsAdapter.SuggestItem;
+import com.android.browser.autocomplete.SuggestiveAutoCompleteTextView;
 import com.android.browser.search.SearchEngine;
 import com.android.browser.search.SearchEngineInfo;
 import com.android.browser.search.SearchEngines;
@@ -32,7 +33,6 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AutoCompleteTextView;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
@@ -42,7 +42,7 @@
  * url/search input view
  * handling suggestions
  */
-public class UrlInputView extends AutoCompleteTextView
+public class UrlInputView extends SuggestiveAutoCompleteTextView
         implements OnEditorActionListener,
         CompletionListener, OnItemClickListener {
 
@@ -261,4 +261,7 @@
         return super.onKeyDown(keyCode, evt);
     }
 
+    public SuggestionsAdapter getAdapter() {
+        return mAdapter;
+    }
 }
diff --git a/src/com/android/browser/autocomplete/SuggestedSpan.java b/src/com/android/browser/autocomplete/SuggestedSpan.java
new file mode 100644
index 0000000..dc04cb2
--- /dev/null
+++ b/src/com/android/browser/autocomplete/SuggestedSpan.java
@@ -0,0 +1,34 @@
+/*
+ * 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.browser.autocomplete;
+
+import android.os.Parcel;
+import android.text.style.ForegroundColorSpan;
+
+/**
+ * Class used to mark the portion of text within {@link SuggestiveEditText} that is suggested.
+ */
+class SuggestedSpan extends ForegroundColorSpan {
+
+    public SuggestedSpan(Parcel src) {
+        super(src);
+    }
+
+    public SuggestedSpan(int color) {
+        super(color);
+    }
+
+}
diff --git a/src/com/android/browser/autocomplete/SuggestedTextController.java b/src/com/android/browser/autocomplete/SuggestedTextController.java
new file mode 100644
index 0000000..e9b74ce
--- /dev/null
+++ b/src/com/android/browser/autocomplete/SuggestedTextController.java
@@ -0,0 +1,508 @@
+/*
+ * 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.browser.autocomplete;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpanWatcher;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+
+import java.util.ArrayList;
+
+import junit.framework.Assert;
+
+
+/**
+ * The query editor can show a suggestion, grayed out following the query that the user has
+ * entered so far. As the user types new characters, these should replace the grayed suggestion
+ * text. This class manages this logic, displaying the suggestion when the user entered text is a
+ * prefix of it, and hiding it otherwise.
+ *
+ * Note, the text in the text view will contain the entire suggestion, not just what the user
+ * entered. Instead of retrieving the text from the text view, {@link #getUserText()} should be
+ * called on this class.
+ */
+public class SuggestedTextController {
+    private static final boolean DBG = false;
+    private static final String TAG = "Browser.SuggestedTextController";
+
+    private final BufferTextWatcher mBufferTextWatcher = new BufferTextWatcher();
+    private final BufferSpanWatcher mBufferSpanWatcher = new BufferSpanWatcher();
+    private final ArrayList<TextChangeWatcher> mTextWatchers;
+    private final TextOwner mTextOwner;
+    private final StringBuffer mUserEntered;
+    private final SuggestedSpan mSuggested;
+    private String mSuggestedText;
+    private TextChangeAttributes mCurrentTextChange;
+    /**
+     * While this is non-null, any changes made to the cursor position or selection are ignored. Is
+     * stored the selection state at the moment when selection change processing was disabled.
+     */
+    private BufferSelection mTextSelectionBeforeIgnoringChanges;
+
+    public SuggestedTextController(final EditText textView, int color) {
+        this(new TextOwner() {
+            @Override
+            public Editable getText() {
+                return textView.getText();
+            }
+            @Override
+            public void addTextChangedListener(TextWatcher watcher) {
+                textView.addTextChangedListener(watcher);
+            }
+            @Override
+            public void removeTextChangedListener(TextWatcher watcher) {
+                textView.removeTextChangedListener(watcher);
+            }
+            @Override
+            public void setText(String text) {
+                textView.setText(text);
+            }
+        }, color);
+    }
+
+    private void initialize(String userText, int selStart, int selEnd, String suggested) {
+        Editable text = mTextOwner.getText();
+
+        if (userText == null) userText = "";
+        String allText = userText;
+        int suggestedStart = allText.length();
+        if (suggested != null && userText != null) {
+            if (suggested.startsWith(userText.toLowerCase())) {
+                allText = suggested;
+            }
+        }
+
+        // allText is at this point either "userText" (not null) or
+        // "suggested" if thats not null and starts with userText.
+        text.replace(0, text.length(), allText);
+        Selection.setSelection(text, selStart, selEnd);
+        mUserEntered.replace(0, mUserEntered.length(), userText);
+        mSuggestedText = suggested;
+        if (suggestedStart < text.length()) {
+            text.setSpan(mSuggested, suggestedStart, text.length(),
+                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        } else {
+            text.removeSpan(mSuggested);
+        }
+        text.setSpan(mBufferSpanWatcher, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        mTextOwner.addTextChangedListener(mBufferTextWatcher);
+        if (DBG) checkInvariant(text);
+    }
+
+    private void assertNotIgnoringSelectionChanges() {
+        if (mTextSelectionBeforeIgnoringChanges != null) {
+            throw new IllegalStateException(
+                    "Illegal operation while cursor movement processing suspended");
+        }
+    }
+
+    public Parcelable saveInstanceState(Parcelable superState) {
+        assertNotIgnoringSelectionChanges();
+        SavedState ss = new SavedState(superState);
+        Editable buffer = mTextOwner.getText();
+        ss.mUserText = getUserText();
+        ss.mSuggestedText = mSuggestedText;
+        ss.mSelStart = Selection.getSelectionStart(buffer);
+        ss.mSelEnd = Selection.getSelectionEnd(buffer);
+        return ss;
+    }
+
+    public Parcelable restoreInstanceState(Parcelable state) {
+        assertNotIgnoringSelectionChanges();
+        if (!(state instanceof SavedState)) return state;
+        SavedState ss = (SavedState) state;
+        if (DBG) {
+            Log.d(TAG, "restoreInstanceState t='" + ss.mUserText + "' suggestion='" +
+                    ss.mSuggestedText + " sel=" + ss.mSelStart + ".." + ss.mSelEnd);
+        }
+        // remove our listeners so we don't get notifications while re-initialising
+        mTextOwner.getText().removeSpan(mBufferSpanWatcher);
+        mTextOwner.removeTextChangedListener(mBufferTextWatcher);
+        // and initialise will re-add the watchers
+        initialize(ss.mUserText, ss.mSelStart, ss.mSelEnd, ss.mSuggestedText);
+        notifyUserEnteredChanged();
+        return ss.getSuperState();
+    }
+
+    /**
+     * Temporarily stop processing cursor movements and selection changes. While cursor movements
+     * are being ignored, the text in the buffer must NOT be changed; doing so will result in an
+     * {@link IllegalStateException} being thrown.
+     *
+     * To stop ignoring cursor movements, call
+     * {@link #resumeCursorMovementHandlingAndApplyChanges()}.
+     */
+    public void suspendCursorMovementHandling() {
+        assertNotIgnoringSelectionChanges();
+        Editable buffer = mTextOwner.getText();
+        mTextSelectionBeforeIgnoringChanges = new BufferSelection(buffer);
+    }
+
+    /**
+     * Start responding to cursor movements and selection changes again. If the cursor or selection
+     * moved while it was being ignored, these changes will be processed now.
+     */
+    public void resumeCursorMovementHandlingAndApplyChanges() {
+        Editable buffer = mTextOwner.getText();
+        BufferSelection oldSelection = mTextSelectionBeforeIgnoringChanges;
+        mTextSelectionBeforeIgnoringChanges = null;
+        BufferSelection newSelection = new BufferSelection(buffer);
+        if (oldSelection.mStart != newSelection.mStart) {
+            mBufferSpanWatcher.onSpanChanged(buffer, Selection.SELECTION_START,
+                    oldSelection.mStart, oldSelection.mStart,
+                    newSelection.mStart, newSelection.mStart);
+        }
+        if (oldSelection.mEnd != newSelection.mEnd) {
+            mBufferSpanWatcher.onSpanChanged(buffer, Selection.SELECTION_END,
+                    oldSelection.mEnd, oldSelection.mEnd,
+                    newSelection.mEnd, newSelection.mEnd);
+        }
+    }
+
+    /**
+     * Sets the current suggested text. A portion of this will be added to the user entered text if
+     * that is a prefix of the suggestion.
+     */
+    public void setSuggestedText(String text) {
+        assertNotIgnoringSelectionChanges();
+        if (!TextUtils.equals(text, mSuggestedText)) {
+            if (DBG) Log.d(TAG, "setSuggestedText(" + text + ")");
+            mSuggestedText = text;
+            if (mCurrentTextChange == null) {
+                mCurrentTextChange = new TextChangeAttributes(0, 0, 0);
+                Editable buffer = mTextOwner.getText();
+                handleTextChanged(buffer);
+            }
+        }
+    }
+
+    /**
+     * Gets the portion of displayed text that is not suggested.
+     */
+    public String getUserText() {
+        assertNotIgnoringSelectionChanges();
+        return mUserEntered.toString();
+    }
+
+    /**
+     * Sets the given text as if it has been entered by the user.
+     */
+    public void setText(String text) {
+        assertNotIgnoringSelectionChanges();
+        if (text == null) text = "";
+        Editable buffer = mTextOwner.getText();
+        buffer.removeSpan(mSuggested);
+        // this will cause a handleTextChanged call
+        buffer.replace(0, text.length(), text);
+    }
+
+    public void addUserTextChangeWatcher(TextChangeWatcher watcher) {
+        mTextWatchers.add(watcher);
+    }
+
+    private void handleTextChanged(Editable newText) {
+        // When we make changes to the buffer from within this function, it results in recursive
+        // calls to beforeTextChanges(), afterTextChanged(). We want to ignore the changes we're
+        // making ourself:
+        if (mCurrentTextChange.isHandled()) return;
+        mCurrentTextChange.setHandled();
+        final int pos = mCurrentTextChange.mPos;
+        final int countBefore = mCurrentTextChange.mCountBefore;
+        final int countAfter = mCurrentTextChange.mCountAfter;
+        final int cursorPos = Selection.getSelectionEnd(newText);
+        if (DBG) {
+            Log.d(TAG, "pos=" + pos +"; countBefore=" + countBefore + "; countAfter=" +
+                    countAfter + "; cursor=" + cursorPos);
+        }
+        mUserEntered.replace(pos, pos + countBefore,
+                newText.subSequence(pos, pos + countAfter).toString());
+        if (DBG) Log.d(TAG, "User entered: '" + mUserEntered + "' all='" + newText + "'");
+        final int userLen = mUserEntered.length();
+        boolean haveSuggested = newText.getSpanStart(mSuggested) != -1;
+        if (mSuggestedText != null &&
+                mSuggestedText.startsWith(mUserEntered.toString().toLowerCase())) {
+            if (haveSuggested) {
+                if (!mSuggestedText.equalsIgnoreCase(newText.toString())) {
+                    if (countAfter > countBefore) {
+                        // net insertion
+                        int len = countAfter - countBefore;
+                        newText.delete(pos + len, pos + len + len);
+                    } else {
+                        // net deletion
+                        newText.replace(userLen, newText.length(),
+                                mSuggestedText.substring(userLen));
+                        if (countBefore == 0) {
+                            // no change to the text - likely just suggested change
+                            Selection.setSelection(newText, cursorPos);
+                        }
+                    }
+                }
+            } else {
+                // no current suggested text - add it
+                newText.insert(userLen, mSuggestedText.substring(userLen));
+                // keep the cursor at the end of the user entered text, if that where it was
+                // before.
+                if (cursorPos == userLen) {
+                    Selection.setSelection(newText, userLen);
+                }
+            }
+            if (userLen == newText.length()) {
+                newText.removeSpan(mSuggested);
+            } else {
+                newText.setSpan(mSuggested, userLen, newText.length(),
+                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
+        } else {
+            if (newText.getSpanStart(mSuggested) != -1) {
+                newText.removeSpan(mSuggested);
+                newText.delete(mUserEntered.length(), newText.length());
+            }
+        }
+        if (DBG) checkInvariant(newText);
+        mCurrentTextChange = null;
+        if (countBefore > 0 || countAfter > 0) {
+            notifyUserEnteredChanged();
+        }
+    }
+
+    private void notifyUserEnteredChanged() {
+        for (TextChangeWatcher watcher : mTextWatchers) {
+            watcher.onTextChanged(mUserEntered.toString());
+        }
+    }
+
+    /**
+     * Basic interface for being notified of changes to some text.
+     */
+    public interface TextChangeWatcher {
+        void onTextChanged(String newText);
+    }
+
+    /**
+     * Interface class to wrap required methods from {@link EditText}, or some other class used
+     * to test without needing an @{link EditText}.
+     */
+    public interface TextOwner {
+        Editable getText();
+        void addTextChangedListener(TextWatcher watcher);
+        void removeTextChangedListener(TextWatcher watcher);
+        void setText(String text);
+    }
+
+    /**
+     * This class stores the parameters passed to {@link BufferTextWatcher#beforeTextChanged},
+     * together with a flag indicating if this invocation has been dealt with yet. We need this
+     * information, together with the parameters passed to
+     * {@link BufferTextWatcher#afterTextChanged}, to restore our internal state when the buffer is
+     * edited.
+     *
+     * Since the changes we make from within {@link BufferTextWatcher#afterTextChanged} also trigger
+     * further recursive calls to {@link BufferTextWatcher#beforeTextChanged} and
+     * {@link BufferTextWatcher#afterTextChanged}, this class helps detect these recursive calls so
+     * they can be ignored.
+     */
+    private static class TextChangeAttributes {
+        public final int mPos;
+        public final int mCountAfter;
+        public final int mCountBefore;
+        private boolean mHandled;
+
+        public TextChangeAttributes(int pos, int countAfter, int countBefore) {
+            mPos = pos;
+            mCountAfter = countAfter;
+            mCountBefore = countBefore;
+        }
+
+        public void setHandled() {
+            mHandled = true;
+        }
+
+        public boolean isHandled() {
+            return mHandled;
+        }
+    }
+
+    /**
+     * Encapsulates the state of the text selection (and cursor) within a text buffer.
+     */
+    private static class BufferSelection {
+        final int mStart;
+        final int mEnd;
+        public BufferSelection(CharSequence text) {
+            mStart = Selection.getSelectionStart(text);
+            mEnd = Selection.getSelectionEnd(text);
+        }
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof BufferSelection)) return super.equals(other);
+            BufferSelection otherSel = (BufferSelection) other;
+            return this.mStart == otherSel.mStart && this.mEnd == otherSel.mEnd;
+        }
+    }
+
+    private class BufferTextWatcher implements TextWatcher {
+        @Override
+        public void afterTextChanged(Editable newText) {
+            if (DBG) {
+                Log.d(TAG, "afterTextChanged('" + newText + "')");
+            }
+            assertNotIgnoringSelectionChanges();
+            handleTextChanged(newText);
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            assertNotIgnoringSelectionChanges();
+            if (mCurrentTextChange == null) {
+                mCurrentTextChange = new TextChangeAttributes(start, after, count);
+            }
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+    }
+
+    private class BufferSpanWatcher implements SpanWatcher {
+        @Override
+        public void onSpanAdded(Spannable text, Object what, int start, int end) {
+        }
+
+        @Override
+        public void onSpanChanged(
+                Spannable text, Object what, int ostart, int oend, int nstart, int nend) {
+            if (mCurrentTextChange != null) return;
+            if (mTextSelectionBeforeIgnoringChanges != null) return;
+            if (what == Selection.SELECTION_END) {
+                if (DBG) Log.d(TAG, "cursor move to " + nend);
+                if (nend > mUserEntered.length()) {
+                    mUserEntered.replace(0, mUserEntered.length(), text.toString());
+                    text.removeSpan(mSuggested);
+                }
+                if (DBG) checkInvariant(text);
+            }
+        }
+
+        @Override
+        public void onSpanRemoved(Spannable text, Object what, int start, int end) {
+        }
+    }
+
+    public static class SavedState extends View.BaseSavedState {
+        String mUserText;
+        String mSuggestedText;
+        int mSelStart;
+        int mSelEnd;
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeString(mUserText);
+            out.writeString(mSuggestedText);
+            out.writeInt(mSelStart);
+            out.writeInt(mSelEnd);
+        }
+
+        @SuppressWarnings("hiding")
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            @Override
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            @Override
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+
+        private SavedState(Parcel in) {
+            super(in);
+            mUserText = in.readString();
+            mSuggestedText = in.readString();
+            mSelStart = in.readInt();
+            mSelEnd = in.readInt();
+        }
+    }
+
+    /*
+     * The remaining functions are used for testing purposes only.
+     * -----------------------------------------------------------
+     */
+
+    /**
+     * Verify that the internal state of this class is consistent.
+     */
+    @VisibleForTesting
+    void checkInvariant(final Spannable s) {
+        int suggestedStart = s.getSpanStart(mSuggested);
+        int suggestedEnd = s.getSpanEnd(mSuggested);
+        int cursorPos = Selection.getSelectionEnd(s);
+        if (suggestedStart == -1 || suggestedEnd == -1) {
+            suggestedStart = suggestedEnd = s.length();
+        }
+        String userEntered = getUserText();
+        Log.d(TAG, "checkInvariant all='" + s + "' (len " + s.length() + ") sug="
+                + suggestedStart + ".." + suggestedEnd + " cursor=" + cursorPos +
+                " ue='" + userEntered + "' (len " + userEntered.length() + ")");
+        int suggestedLen = suggestedEnd - suggestedStart;
+        Assert.assertEquals("Sum of user and suggested text lengths doesn't match total length",
+                s.length(), userEntered.length() + suggestedLen);
+        Assert.assertEquals("End of user entered text doesn't match start of suggested",
+                suggestedStart, userEntered.length());
+        Assert.assertTrue("user entered text does not match start of buffer",
+                userEntered.toString().equalsIgnoreCase(
+                        s.subSequence(0, suggestedStart).toString()));
+        if (mSuggestedText != null && suggestedStart < s.length()) {
+            Assert.assertTrue("User entered is not a prefix of suggested",
+                    mSuggestedText.startsWith(userEntered.toString().toLowerCase()));
+            Assert.assertTrue("Suggested text does not match buffer contents",
+                    mSuggestedText.equalsIgnoreCase(s.toString().toLowerCase()));
+        }
+        if (mSuggestedText == null) {
+            Assert.assertEquals("Non-zero suggention length with null suggestion", 0, suggestedLen);
+        } else {
+            Assert.assertTrue("Suggestion text longer than suggestion (" + mSuggestedText.length() +
+                    ">" + suggestedLen + ")", suggestedLen <= mSuggestedText.length());
+        }
+        Assert.assertTrue("Cursor within suggested part", cursorPos <= suggestedStart);
+    }
+
+    @VisibleForTesting
+    SuggestedTextController(TextOwner textOwner, int color) {
+        mUserEntered = new StringBuffer();
+        mSuggested = new SuggestedSpan(color);
+        mTextOwner = textOwner;
+        mTextWatchers = new ArrayList<TextChangeWatcher>();
+        initialize(null, 0, 0, null);
+    }
+}
diff --git a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
new file mode 100644
index 0000000..d93066c
--- /dev/null
+++ b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
@@ -0,0 +1,828 @@
+/*
+ * 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.browser.autocomplete;
+
+import com.android.browser.SuggestionsAdapter;
+import com.android.browser.SuggestionsAdapter.SuggestItem;
+import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
+import com.android.internal.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Rect;
+import android.os.Parcelable;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.AbsSavedState;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ListAdapter;
+import android.widget.ListPopupWindow;
+import android.widget.TextView;
+
+
+/**
+ * This is a stripped down version of the framework AutoCompleteTextView
+ * class with added support for displaying completions in-place. Note that
+ * this cannot be implemented as a subclass of the above without making
+ * substantial changes to it and its descendants.
+ *
+ * @see android.widget.AutoCompleteTextView
+ */
+public class SuggestiveAutoCompleteTextView extends EditText implements Filter.FilterListener {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "SuggestiveAutoCompleteTextView";
+
+    private CharSequence mHintText;
+    private TextView mHintView;
+    private int mHintResource;
+
+    private SuggestionsAdapter mAdapter;
+    private Filter mFilter;
+    private int mThreshold;
+
+    private ListPopupWindow mPopup;
+    private int mDropDownAnchorId;
+
+    private AdapterView.OnItemClickListener mItemClickListener;
+
+    private boolean mDropDownDismissedOnCompletion = true;
+
+    private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
+    private boolean mOpenBefore;
+
+    // Set to true when text is set directly and no filtering shall be performed
+    private boolean mBlockCompletion;
+
+    // When set, an update in the underlying adapter will update the result list popup.
+    // Set to false when the list is hidden to prevent asynchronous updates to popup the list again.
+    private boolean mPopupCanBeUpdated = true;
+
+    private PassThroughClickListener mPassThroughClickListener;
+    private PopupDataSetObserver mObserver;
+    private SuggestedTextController mController;
+
+    public SuggestiveAutoCompleteTextView(Context context) {
+        this(context, null);
+    }
+
+    public SuggestiveAutoCompleteTextView(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.autoCompleteTextViewStyle);
+    }
+
+    public SuggestiveAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        mController = new SuggestedTextController(this, getHintTextColors().getDefaultColor());
+        mPopup = new ListPopupWindow(context, attrs,
+                 R.attr.autoCompleteTextViewStyle);
+        mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+        mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.AutoCompleteTextView, defStyle, 0);
+
+        mThreshold = a.getInt(
+                R.styleable.AutoCompleteTextView_completionThreshold, 2);
+
+        mPopup.setListSelector(a.getDrawable(R.styleable.AutoCompleteTextView_dropDownSelector));
+        mPopup.setVerticalOffset((int)
+                a.getDimension(R.styleable.AutoCompleteTextView_dropDownVerticalOffset, 0.0f));
+        mPopup.setHorizontalOffset((int)
+                a.getDimension(R.styleable.AutoCompleteTextView_dropDownHorizontalOffset, 0.0f));
+
+        // Get the anchor's id now, but the view won't be ready, so wait to actually get the
+        // view and store it in mDropDownAnchorView lazily in getDropDownAnchorView later.
+        // Defaults to NO_ID, in which case the getDropDownAnchorView method will simply return
+        // this TextView, as a default anchoring point.
+        mDropDownAnchorId = a.getResourceId(
+                R.styleable.AutoCompleteTextView_dropDownAnchor, View.NO_ID);
+
+        // For dropdown width, the developer can specify a specific width, or MATCH_PARENT
+        // (for full screen width) or WRAP_CONTENT (to match the width of the anchored view).
+        mPopup.setWidth(a.getLayoutDimension(
+                R.styleable.AutoCompleteTextView_dropDownWidth,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
+        mPopup.setHeight(a.getLayoutDimension(
+                R.styleable.AutoCompleteTextView_dropDownHeight,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
+
+        mHintResource = a.getResourceId(R.styleable.AutoCompleteTextView_completionHintView,
+                R.layout.simple_dropdown_hint);
+
+        mPopup.setOnItemClickListener(new DropDownItemClickListener());
+        setCompletionHint(a.getText(R.styleable.AutoCompleteTextView_completionHint));
+
+        // Always turn on the auto complete input type flag, since it
+        // makes no sense to use this widget without it.
+        int inputType = getInputType();
+        if ((inputType&EditorInfo.TYPE_MASK_CLASS)
+                == EditorInfo.TYPE_CLASS_TEXT) {
+            inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE;
+            setRawInputType(inputType);
+        }
+
+        a.recycle();
+
+        setFocusable(true);
+
+        mController.addUserTextChangeWatcher(new MyWatcher());
+
+        mPassThroughClickListener = new PassThroughClickListener();
+        super.setOnClickListener(mPassThroughClickListener);
+    }
+
+    @Override
+    public void setOnClickListener(OnClickListener listener) {
+        mPassThroughClickListener.mWrapped = listener;
+    }
+
+    /**
+     * Private hook into the on click event, dispatched from {@link PassThroughClickListener}
+     */
+    private void onClickImpl() {
+        // If the dropdown is showing, bring the keyboard to the front
+        // when the user touches the text field.
+        if (isPopupShowing()) {
+            ensureImeVisible(true);
+        }
+    }
+
+    /**
+     * <p>Sets the optional hint text that is displayed at the bottom of the
+     * the matching list.  This can be used as a cue to the user on how to
+     * best use the list, or to provide extra information.</p>
+     *
+     * @param hint the text to be displayed to the user
+     *
+     * @attr ref android.R.styleable#AutoCompleteTextView_completionHint
+     */
+    private void setCompletionHint(CharSequence hint) {
+        mHintText = hint;
+        if (hint != null) {
+            if (mHintView == null) {
+                final TextView hintView = (TextView) LayoutInflater.from(getContext()).inflate(
+                        mHintResource, null).findViewById(R.id.text1);
+                hintView.setText(mHintText);
+                mHintView = hintView;
+                mPopup.setPromptView(hintView);
+            } else {
+                mHintView.setText(hint);
+            }
+        } else {
+            mPopup.setPromptView(null);
+            mHintView = null;
+        }
+    }
+
+    protected int getDropDownWidth() {
+        return mPopup.getWidth();
+    }
+
+    public void setDropDownWidth(int width) {
+        mPopup.setWidth(width);
+    }
+
+    protected void setDropDownVerticalOffset(int offset) {
+        mPopup.setVerticalOffset(offset);
+    }
+
+    public void setDropDownHorizontalOffset(int offset) {
+        mPopup.setHorizontalOffset(offset);
+    }
+
+    protected int getDropDownHorizontalOffset() {
+        return mPopup.getHorizontalOffset();
+    }
+
+    protected void setThreshold(int threshold) {
+        if (threshold <= 0) {
+            threshold = 1;
+        }
+
+        mThreshold = threshold;
+    }
+
+    protected void setOnItemClickListener(AdapterView.OnItemClickListener l) {
+        mItemClickListener = l;
+    }
+
+    public void setAdapter(SuggestionsAdapter adapter) {
+        if (mObserver == null) {
+            mObserver = new PopupDataSetObserver();
+        } else if (mAdapter != null) {
+            mAdapter.unregisterDataSetObserver(mObserver);
+        }
+        mAdapter = adapter;
+        if (mAdapter != null) {
+            mFilter = mAdapter.getFilter();
+            adapter.registerDataSetObserver(mObserver);
+        } else {
+            mFilter = null;
+        }
+
+        mPopup.setAdapter(mAdapter);
+    }
+
+    @Override
+    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && isPopupShowing()
+                && !mPopup.isDropDownAlwaysVisible()) {
+            // special case for the back key, we do not even try to send it
+            // to the drop down list but instead, consume it immediately
+            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+                KeyEvent.DispatcherState state = getKeyDispatcherState();
+                if (state != null) {
+                    state.startTracking(event, this);
+                }
+                return true;
+            } else if (event.getAction() == KeyEvent.ACTION_UP) {
+                KeyEvent.DispatcherState state = getKeyDispatcherState();
+                if (state != null) {
+                    state.handleUpEvent(event);
+                }
+                if (event.isTracking() && !event.isCanceled()) {
+                    dismissDropDown();
+                    return true;
+                }
+            }
+        }
+        return super.onKeyPreIme(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        boolean consumed = mPopup.onKeyUp(keyCode, event);
+        if (consumed) {
+            switch (keyCode) {
+            // if the list accepts the key events and the key event
+            // was a click, the text view gets the selected item
+            // from the drop down as its content
+            case KeyEvent.KEYCODE_ENTER:
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_TAB:
+                if (event.hasNoModifiers()) {
+                    performCompletion();
+                }
+                return true;
+            }
+        }
+
+        if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) {
+            performCompletion();
+            return true;
+        }
+
+        return super.onKeyUp(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mPopup.onKeyDown(keyCode, event)) {
+            return true;
+        }
+
+        if (!isPopupShowing()) {
+            switch(keyCode) {
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                if (event.hasNoModifiers()) {
+                    performValidation();
+                }
+            }
+        }
+
+        if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) {
+            return true;
+        }
+
+        mLastKeyCode = keyCode;
+        boolean handled = super.onKeyDown(keyCode, event);
+        mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
+
+        if (handled && isPopupShowing()) {
+            clearListSelection();
+        }
+
+        return handled;
+    }
+
+    /**
+     * Returns <code>true</code> if the amount of text in the field meets
+     * or exceeds the {@link #getThreshold} requirement.  You can override
+     * this to impose a different standard for when filtering will be
+     * triggered.
+     */
+    private boolean enoughToFilter() {
+        if (DEBUG) Log.v(TAG, "Enough to filter: len=" + getText().length()
+                + " threshold=" + mThreshold);
+        return getText().length() >= mThreshold;
+    }
+
+    /**
+     * This is used to watch for edits to the text view.  Note that we call
+     * to methods on the auto complete text view class so that we can access
+     * private vars without going through thunks.
+     */
+    private class MyWatcher implements TextWatcher, TextChangeWatcher {
+        @Override
+        public void afterTextChanged(Editable s) {
+            doAfterTextChanged();
+        }
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            doBeforeTextChanged();
+        }
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+        @Override
+        public void onTextChanged(String newText) {
+            doAfterTextChanged();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    protected void setBlockCompletion(boolean block) {
+        mBlockCompletion = block;
+    }
+
+    void doBeforeTextChanged() {
+        if (mBlockCompletion) return;
+
+        // when text is changed, inserted or deleted, we attempt to show
+        // the drop down
+        mOpenBefore = isPopupShowing();
+        if (DEBUG) Log.v(TAG, "before text changed: open=" + mOpenBefore);
+    }
+
+    void doAfterTextChanged() {
+        if (DEBUG) Log.d(TAG, "doAfterTextChanged(" + getText() + ")");
+        if (mBlockCompletion) return;
+
+        // if the list was open before the keystroke, but closed afterwards,
+        // then something in the keystroke processing (an input filter perhaps)
+        // called performCompletion() and we shouldn't do any more processing.
+        if (DEBUG) Log.v(TAG, "after text changed: openBefore=" + mOpenBefore
+                + " open=" + isPopupShowing());
+        if (mOpenBefore && !isPopupShowing()) {
+            return;
+        }
+
+        // the drop down is shown only when a minimum number of characters
+        // was typed in the text view
+        if (enoughToFilter()) {
+            if (mFilter != null) {
+                mPopupCanBeUpdated = true;
+                performFiltering(mController.getUserText(), mLastKeyCode);
+                buildImeCompletions();
+            }
+        } else {
+            // drop down is automatically dismissed when enough characters
+            // are deleted from the text view
+            if (!mPopup.isDropDownAlwaysVisible()) {
+                dismissDropDown();
+            }
+            if (mFilter != null) {
+                mFilter.filter(null);
+            }
+        }
+    }
+
+    /**
+     * <p>Indicates whether the popup menu is showing.</p>
+     *
+     * @return true if the popup menu is showing, false otherwise
+     */
+    protected boolean isPopupShowing() {
+        return mPopup.isShowing();
+    }
+
+    /**
+     * <p>Converts the selected item from the drop down list into a sequence
+     * of character that can be used in the edit box.</p>
+     *
+     * @param selectedItem the item selected by the user for completion
+     *
+     * @return a sequence of characters representing the selected suggestion
+     */
+    protected CharSequence convertSelectionToString(Object selectedItem) {
+        return mFilter.convertResultToString(selectedItem);
+    }
+
+    /**
+     * <p>Clear the list selection.  This may only be temporary, as user input will often bring
+     * it back.
+     */
+    private void clearListSelection() {
+        mPopup.clearListSelection();
+    }
+
+    /**
+     * <p>Starts filtering the content of the drop down list. The filtering
+     * pattern is the content of the edit box. Subclasses should override this
+     * method to filter with a different pattern, for instance a substring of
+     * <code>text</code>.</p>
+     *
+     * @param text the filtering pattern
+     * @param keyCode the last character inserted in the edit box; beware that
+     * this will be null when text is being added through a soft input method.
+     */
+    @SuppressWarnings({ "UnusedDeclaration" })
+    protected void performFiltering(CharSequence text, int keyCode) {
+        if (DEBUG) Log.d(TAG, "performFiltering(" + text + ")");
+
+        mFilter.filter(text, this);
+    }
+
+    /**
+     * <p>Performs the text completion by converting the selected item from
+     * the drop down list into a string, replacing the text box's content with
+     * this string and finally dismissing the drop down menu.</p>
+     */
+    private void performCompletion() {
+        performCompletion(null, -1, -1);
+    }
+
+    @Override
+    public void onCommitCompletion(CompletionInfo completion) {
+        if (isPopupShowing()) {
+            mBlockCompletion = true;
+            replaceText(completion.getText());
+            mBlockCompletion = false;
+
+            mPopup.performItemClick(completion.getPosition());
+        }
+    }
+
+    private void performCompletion(View selectedView, int position, long id) {
+        if (isPopupShowing()) {
+            Object selectedItem;
+            if (position < 0) {
+                selectedItem = mPopup.getSelectedItem();
+            } else {
+                selectedItem = mAdapter.getItem(position);
+            }
+            if (selectedItem == null) {
+                Log.w(TAG, "performCompletion: no selected item");
+                return;
+            }
+
+            mBlockCompletion = true;
+            replaceText(convertSelectionToString(selectedItem));
+            mBlockCompletion = false;
+
+            if (mItemClickListener != null) {
+                final ListPopupWindow list = mPopup;
+
+                if (selectedView == null || position < 0) {
+                    selectedView = list.getSelectedView();
+                    position = list.getSelectedItemPosition();
+                    id = list.getSelectedItemId();
+                }
+                mItemClickListener.onItemClick(list.getListView(), selectedView, position, id);
+            }
+        }
+
+        if (mDropDownDismissedOnCompletion && !mPopup.isDropDownAlwaysVisible()) {
+            dismissDropDown();
+        }
+    }
+
+    /**
+     * <p>Performs the text completion by replacing the current text by the
+     * selected item. Subclasses should override this method to avoid replacing
+     * the whole content of the edit box.</p>
+     *
+     * @param text the selected suggestion in the drop down list
+     */
+    protected void replaceText(CharSequence text) {
+        clearComposingText();
+
+        setText(text);
+        // make sure we keep the caret at the end of the text view
+        Editable spannable = getText();
+        Selection.setSelection(spannable, spannable.length());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onFilterComplete(int count) {
+        updateDropDownForFilter(count);
+    }
+
+    private void updateDropDownForFilter(int count) {
+        // Not attached to window, don't update drop-down
+        if (getWindowVisibility() == View.GONE) return;
+
+        /*
+         * This checks enoughToFilter() again because filtering requests
+         * are asynchronous, so the result may come back after enough text
+         * has since been deleted to make it no longer appropriate
+         * to filter.
+         */
+
+        final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
+        if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter() &&
+                mController.getUserText().length() > 0) {
+            if (hasFocus() && hasWindowFocus() && mPopupCanBeUpdated) {
+                showDropDown();
+            }
+        } else if (!dropDownAlwaysVisible && isPopupShowing()) {
+            dismissDropDown();
+            // When the filter text is changed, the first update from the adapter may show an empty
+            // count (when the query is being performed on the network). Future updates when some
+            // content has been retrieved should still be able to update the list.
+            mPopupCanBeUpdated = true;
+        }
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        if (!hasWindowFocus && !mPopup.isDropDownAlwaysVisible()) {
+            dismissDropDown();
+        }
+    }
+
+    @Override
+    protected void onDisplayHint(int hint) {
+        super.onDisplayHint(hint);
+        switch (hint) {
+            case INVISIBLE:
+                if (!mPopup.isDropDownAlwaysVisible()) {
+                    dismissDropDown();
+                }
+                break;
+        }
+    }
+
+    @Override
+    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+        // TextView makes several cursor movements when gaining focus, and this interferes with
+        // the suggested vs user entered text. Tell the controller to temporarily ignore cursor
+        // movements while this is going on.
+        mController.suspendCursorMovementHandling();
+
+        super.onFocusChanged(focused, direction, previouslyFocusedRect);
+        // Perform validation if the view is losing focus.
+        if (!focused) {
+            performValidation();
+        }
+        if (!focused && !mPopup.isDropDownAlwaysVisible()) {
+            dismissDropDown();
+        }
+
+        mController.resumeCursorMovementHandlingAndApplyChanges();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        dismissDropDown();
+        super.onDetachedFromWindow();
+    }
+
+    /**
+     * <p>Closes the drop down if present on screen.</p>
+     */
+    protected void dismissDropDown() {
+        InputMethodManager imm = InputMethodManager.peekInstance();
+        if (imm != null) {
+            imm.displayCompletions(this, null);
+        }
+        mPopup.dismiss();
+        mPopupCanBeUpdated = false;
+    }
+
+    @Override
+    protected boolean setFrame(final int l, int t, final int r, int b) {
+        boolean result = super.setFrame(l, t, r, b);
+
+        if (isPopupShowing()) {
+            showDropDown();
+        }
+
+        return result;
+    }
+
+    /**
+     * Ensures that the drop down is not obscuring the IME.
+     * @param visible whether the ime should be in front. If false, the ime is pushed to
+     * the background.
+     * @hide internal used only here and SearchDialog
+     */
+    private void ensureImeVisible(boolean visible) {
+        mPopup.setInputMethodMode(visible
+                ? ListPopupWindow.INPUT_METHOD_NEEDED : ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
+        showDropDown();
+    }
+
+    /**
+     * <p>Displays the drop down on screen.</p>
+     */
+    protected void showDropDown() {
+        if (mPopup.getAnchorView() == null) {
+            if (mDropDownAnchorId != View.NO_ID) {
+                mPopup.setAnchorView(getRootView().findViewById(mDropDownAnchorId));
+            } else {
+                mPopup.setAnchorView(this);
+            }
+        }
+        if (!isPopupShowing()) {
+            // Make sure the list does not obscure the IME when shown for the first time.
+            mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
+        }
+        mPopup.show();
+    }
+
+    private void buildImeCompletions() {
+        final ListAdapter adapter = mAdapter;
+        if (adapter != null) {
+            InputMethodManager imm = InputMethodManager.peekInstance();
+            if (imm != null) {
+                final int count = Math.min(adapter.getCount(), 20);
+                CompletionInfo[] completions = new CompletionInfo[count];
+                int realCount = 0;
+
+                for (int i = 0; i < count; i++) {
+                    if (adapter.isEnabled(i)) {
+                        realCount++;
+                        Object item = adapter.getItem(i);
+                        long id = adapter.getItemId(i);
+                        completions[i] = new CompletionInfo(id, i,
+                                convertSelectionToString(item));
+                    }
+                }
+
+                if (realCount != count) {
+                    CompletionInfo[] tmp = new CompletionInfo[realCount];
+                    System.arraycopy(completions, 0, tmp, 0, realCount);
+                    completions = tmp;
+                }
+
+                imm.displayCompletions(this, completions);
+            }
+        }
+    }
+
+    private void performValidation() {
+    }
+
+    /**
+     * Returns the Filter obtained from {@link Filterable#getFilter},
+     * or <code>null</code> if {@link #setAdapter} was not called with
+     * a Filterable.
+     */
+    protected Filter getFilter() {
+        return mFilter;
+    }
+
+    private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
+        @Override
+        public void onItemClick(AdapterView parent, View v, int position, long id) {
+            performCompletion(v, position, id);
+        }
+    }
+
+    /**
+     * Allows us a private hook into the on click event without preventing users from setting
+     * their own click listener.
+     */
+    private class PassThroughClickListener implements OnClickListener {
+
+        private View.OnClickListener mWrapped;
+
+        /** {@inheritDoc} */
+        @Override
+        public void onClick(View v) {
+            onClickImpl();
+
+            if (mWrapped != null) mWrapped.onClick(v);
+        }
+    }
+
+    private class PopupDataSetObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            if (mAdapter != null) {
+                // If the popup is not showing already, showing it will cause
+                // the list of data set observers attached to the adapter to
+                // change. We can't do it from here, because we are in the middle
+                // of iterating through the list of observers.
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        final SuggestionsAdapter adapter = mAdapter;
+                        if (adapter != null) {
+                            // This will re-layout, thus resetting mDataChanged, so that the
+                            // listView click listener stays responsive
+                            updateDropDownForFilter(adapter.getCount());
+                        }
+
+                        updateText(adapter);
+                    }
+                });
+            }
+        }
+    }
+
+    private void updateText(SuggestionsAdapter adapter) {
+        // FIXME: Turn this on only when instant is being used.
+        // if (!BrowserSettings.getInstance().useInstant()) {
+        //     return;
+        // }
+
+        if (!isPopupShowing()) {
+            setSuggestedText(null);
+            return;
+        }
+
+        if (mAdapter.getCount() > 0 && !TextUtils.isEmpty(mController.getUserText())) {
+            SuggestItem item = adapter.getItem(0);
+            setSuggestedText(item.title);
+        }
+    }
+
+    @Override
+    public void setText(CharSequence text, BufferType type) {
+        Editable buffer = getEditableText();
+        if (text == null) text = "";
+        // if we already have a buffer, we must not replace it with a new one as this will break
+        // mController. Write the new text into the existing buffer instead.
+        if (buffer == null) {
+            super.setText(text, type);
+        } else {
+            buffer.replace(0, buffer.length(), text);
+        }
+    }
+
+    public void setText(CharSequence text, boolean filter) {
+        if (filter) {
+            setText(text);
+        } else {
+            mBlockCompletion = true;
+            setText(text);
+            mBlockCompletion = false;
+        }
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        if (superState instanceof TextView.SavedState) {
+            // get rid of TextView's saved state, we override it.
+            superState = ((TextView.SavedState) superState).getSuperState();
+        }
+        if (superState == null) {
+            superState = AbsSavedState.EMPTY_STATE;
+        }
+        return mController.saveInstanceState(superState);
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        super.onRestoreInstanceState(mController.restoreInstanceState(state));
+    }
+
+    public void addQueryTextWatcher(final SuggestedTextController.TextChangeWatcher watcher) {
+        mController.addUserTextChangeWatcher(watcher);
+    }
+
+    public void setSuggestedText(String text) {
+        mController.setSuggestedText(text);
+    }
+}
diff --git a/src/com/android/browser/search/SearchEngineInfo.java b/src/com/android/browser/search/SearchEngineInfo.java
index 6f0b1d5..af6fa70 100644
--- a/src/com/android/browser/search/SearchEngineInfo.java
+++ b/src/com/android/browser/search/SearchEngineInfo.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -58,9 +59,12 @@
      */
     public SearchEngineInfo(Context context, String name) throws IllegalArgumentException {
         mName = name;
-
         Resources res = context.getResources();
+
         int id_data = res.getIdentifier(name, "array", context.getPackageName());
+        if (id_data == 0) {
+            throw new IllegalArgumentException("No resources found for " + name);
+        }
         mSearchEngineData = res.getStringArray(id_data);
 
         if (mSearchEngineData == null) {
