diff --git a/res/xml-sw600dp/lab_preferences.xml b/res/xml-sw600dp/lab_preferences.xml
index 0edc919..a7151e0 100644
--- a/res/xml-sw600dp/lab_preferences.xml
+++ b/res/xml-sw600dp/lab_preferences.xml
@@ -21,9 +21,4 @@
         android:defaultValue="false"
         android:title="@string/pref_lab_quick_controls"
         android:summary="@string/pref_lab_quick_controls_summary" />
-    <CheckBoxPreference
-        android:key="use_instant_search"
-        android:defaultValue="false"
-        android:title="@string/pref_use_instant_search"
-        android:summary="@string/pref_use_instant_search_summary" />
 </PreferenceScreen>
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index ee308f9..e3b620a 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -493,11 +493,6 @@
     }
 
     @Override
-    public void registerDropdownChangeListener(DropdownChangeListener d) {
-        mNavigationBar.registerDropdownChangeListener(d);
-    }
-
-    @Override
     public void showComboView(ComboViews startingView, Bundle extras) {
         Intent intent = new Intent(mActivity, ComboViewActivity.class);
         intent.putExtra(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name());
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 0b8191a..2369554 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -146,10 +146,6 @@
         if (sInitialized) {
             syncSharedSettings();
         }
-
-        if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
-             ((InstantSearchEngine) mSearchEngine).setController(mController);
-        }
     }
 
     public void startManagingSettings(WebSettings settings) {
@@ -355,9 +351,6 @@
         if (PREF_SEARCH_ENGINE.equals(key)) {
             updateSearchEngine(false);
         }
-        if (PREF_USE_INSTANT_SEARCH.equals(key)) {
-            updateSearchEngine(true);
-        }
         if (PREF_FULLSCREEN.equals(key)) {
             if (mController.getUi() != null) {
                 mController.getUi().setFullscreen(useFullscreen());
@@ -426,10 +419,6 @@
                 mSearchEngine.close();
              }
             mSearchEngine = SearchEngines.get(mContext, searchEngineName);
-
-             if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
-                 ((InstantSearchEngine) mSearchEngine).setController(mController);
-             }
          }
     }
 
@@ -794,10 +783,6 @@
         return HomeProvider.MOST_VISITED.equals(getHomePage());
     }
 
-    public boolean useInstantSearch() {
-        return mPrefs.getBoolean(PREF_USE_INSTANT_SEARCH, false);
-    }
-
     public boolean useFullscreen() {
         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
     }
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 9402a77..2a57edf 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -80,7 +80,6 @@
 
 import com.android.browser.IntentHandler.UrlData;
 import com.android.browser.UI.ComboViews;
-import com.android.browser.UI.DropdownChangeListener;
 import com.android.browser.provider.BrowserProvider;
 import com.android.browser.provider.BrowserProvider2.Thumbnails;
 import com.android.browser.provider.SnapshotProvider.Snapshots;
@@ -2744,11 +2743,6 @@
         mActivity.startActivityForResult(intent, AUTOFILL_SETUP);
     }
 
-    @Override
-    public void registerDropdownChangeListener(DropdownChangeListener d) {
-        mUi.registerDropdownChangeListener(d);
-    }
-
     public boolean onSearchRequested() {
         mUi.editUrl(false);
         return true;
diff --git a/src/com/android/browser/InstantSearchEngine.java b/src/com/android/browser/InstantSearchEngine.java
deleted file mode 100644
index 7176c0a..0000000
--- a/src/com/android/browser/InstantSearchEngine.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.browser;
-
-import com.android.browser.Controller;
-import com.android.browser.R;
-import com.android.browser.UI.DropdownChangeListener;
-import com.android.browser.provider.BrowserProvider;
-import com.android.browser.search.SearchEngine;
-
-import android.app.SearchManager;
-import android.content.Context;
-import android.database.AbstractCursor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.LruCache;
-import android.webkit.SearchBox;
-import android.webkit.WebView;
-
-import java.util.Collections;
-import java.util.List;
-
-public class InstantSearchEngine implements SearchEngine, DropdownChangeListener {
-    private static final String TAG = "Browser.InstantSearchEngine";
-    private static final boolean DBG = false;
-
-    private Controller mController;
-    private SearchBox mSearchBox;
-    private final BrowserSearchboxListener mListener = new BrowserSearchboxListener();
-    private int mHeight;
-
-    private String mInstantBaseUrl;
-    private final Context mContext;
-    // Used for startSearch( ) calls if for some reason instant
-    // is off, or no searchbox is present.
-    private final SearchEngine mWrapped;
-
-    public InstantSearchEngine(Context context, SearchEngine wrapped) {
-        mContext = context.getApplicationContext();
-        mWrapped = wrapped;
-    }
-
-    public void setController(Controller controller) {
-        mController = controller;
-    }
-
-    @Override
-    public String getName() {
-        return SearchEngine.GOOGLE;
-    }
-
-    @Override
-    public CharSequence getLabel() {
-        return mContext.getResources().getString(R.string.instant_search_label);
-    }
-
-    @Override
-    public void startSearch(Context context, String query, Bundle appData, String extraData) {
-        if (DBG) Log.d(TAG, "startSearch(" + query + ")");
-
-        switchSearchboxIfNeeded();
-
-        // If for some reason we are in a bad state, ensure that the
-        // user gets default search results at the very least.
-        if (mSearchBox == null || !isInstantPage()) {
-            mWrapped.startSearch(context, query, appData, extraData);
-            return;
-        }
-
-        mSearchBox.setQuery(query);
-        mSearchBox.setVerbatim(true);
-        mSearchBox.onsubmit(null);
-    }
-
-    private final class BrowserSearchboxListener extends SearchBox.SearchBoxListener {
-        /*
-         * The maximum number of out of order suggestions we accept
-         * before giving up the wait.
-         */
-        private static final int MAX_OUT_OF_ORDER = 5;
-
-        /*
-         * We wait for suggestions in increments of 600ms. This is primarily to
-         * guard against suggestions arriving out of order.
-         */
-        private static final int WAIT_INCREMENT_MS = 600;
-
-        /*
-         * A cache of suggestions received, keyed by the queries they were
-         * received for.
-         */
-        private final LruCache<String, List<String>> mSuggestions =
-                new LruCache<String, List<String>>(20);
-
-        /*
-         * The last set of suggestions received. We use this reduce UI flicker
-         * in case there is a delay in recieving suggestions.
-         */
-        private List<String> mLatestSuggestion = Collections.emptyList();
-
-        @Override
-        public synchronized void onSuggestionsReceived(String query, List<String> suggestions) {
-            if (DBG) Log.d(TAG, "onSuggestionsReceived(" + query + ")");
-
-            if (!TextUtils.isEmpty(query)) {
-                mSuggestions.put(query, suggestions);
-                mLatestSuggestion = suggestions;
-            }
-
-            notifyAll();
-        }
-
-        public synchronized List<String> tryWaitForSuggestions(String query) {
-            if (DBG) Log.d(TAG, "tryWait(" + query + ")");
-
-            int numWaitReturns = 0;
-
-            // This slightly unusual waiting construct is used to safeguard
-            // to some extent against suggestions arriving out of order. We
-            // wait for upto 5 notifyAll( ) calls to check if we received
-            // suggestions for a given query.
-            while (mSuggestions.get(query) == null)  {
-                try {
-                    wait(WAIT_INCREMENT_MS);
-                    ++numWaitReturns;
-                    if (numWaitReturns > MAX_OUT_OF_ORDER) {
-                        // We've waited too long for suggestions to be returned.
-                        // return the last available suggestion.
-                        break;
-                    }
-                } catch (InterruptedException e) {
-                    return Collections.emptyList();
-                }
-            }
-
-            List<String> suggestions = mSuggestions.get(query);
-            if (suggestions == null) {
-                return mLatestSuggestion;
-            }
-
-            return suggestions;
-        }
-
-        public synchronized void clear() {
-            mSuggestions.evictAll();
-        }
-    }
-
-    private WebView getCurrentWebview() {
-        if (mController != null) {
-            return mController.getTabControl().getCurrentTopWebView();
-        }
-
-        return null;
-    }
-
-    /**
-     * Attaches the searchbox to the right browser page, i.e, the currently
-     * visible tab.
-     */
-    private void switchSearchboxIfNeeded() {
-        final WebView current = getCurrentWebview();
-        if (current == null) {
-            return;
-        }
-
-        final SearchBox searchBox = current.getSearchBox();
-        if (searchBox != mSearchBox) {
-            if (mSearchBox != null) {
-                mSearchBox.removeSearchBoxListener(mListener);
-                mListener.clear();
-            }
-            mSearchBox = searchBox;
-            if (mSearchBox != null) {
-                mSearchBox.addSearchBoxListener(mListener);
-            }
-        }
-    }
-
-    private boolean isInstantPage() {
-        final WebView current = getCurrentWebview();
-        if (current == null) {
-            return false;
-        }
-
-        final String currentUrl = mController.getCurrentTab().getUrl();
-
-        if (currentUrl != null) {
-            Uri uri = Uri.parse(currentUrl);
-            final String host = uri.getHost();
-            final String path = uri.getPath();
-
-            // Is there a utility class that does this ?
-            if (path != null && host != null) {
-                return host.startsWith("www.google.") &&
-                        (path.startsWith("/search") || path.startsWith("/webhp"));
-            }
-            return false;
-        }
-
-        return false;
-    }
-
-    private void loadInstantPage() {
-        mController.getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                final WebView current = getCurrentWebview();
-                if (current != null) {
-                    current.loadUrl(getInstantBaseUrl());
-                }
-            }
-        });
-    }
-
-    /**
-     * Queries for a given search term and returns a cursor containing
-     * suggestions ordered by best match.
-     */
-    @Override
-    public Cursor getSuggestions(Context context, String query) {
-        if (DBG) Log.d(TAG, "getSuggestions(" + query + ")");
-        if (query == null) {
-            return null;
-        }
-
-        if (!isInstantPage()) {
-            loadInstantPage();
-        }
-
-        switchSearchboxIfNeeded();
-
-        mController.registerDropdownChangeListener(this);
-
-        if (mSearchBox == null) {
-            return mWrapped.getSuggestions(context, query);
-        }
-
-        mSearchBox.setDimensions(0, 0, 0, mHeight);
-        mSearchBox.onresize(null);
-
-        if (TextUtils.isEmpty(query)) {
-            // To force the SRP to render an empty (no results) page.
-            mSearchBox.setVerbatim(true);
-        } else {
-            mSearchBox.setVerbatim(false);
-        }
-        mSearchBox.setQuery(query);
-        mSearchBox.onchange(null);
-
-        // Don't bother waiting for suggestions for an empty query. We still
-        // set the query so that the SRP clears itself.
-        if (TextUtils.isEmpty(query)) {
-            return new SuggestionsCursor(Collections.<String>emptyList());
-        } else {
-            return new SuggestionsCursor(mListener.tryWaitForSuggestions(query));
-        }
-    }
-
-    @Override
-    public boolean supportsSuggestions() {
-        return true;
-    }
-
-    @Override
-    public void close() {
-        if (mController != null) {
-            mController.registerDropdownChangeListener(null);
-        }
-        if (mSearchBox != null) {
-            mSearchBox.removeSearchBoxListener(mListener);
-        }
-        mListener.clear();
-        mWrapped.close();
-    }
-
-    @Override
-    public boolean supportsVoiceSearch() {
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return "InstantSearchEngine {" + hashCode() + "}";
-    }
-
-    @Override
-    public boolean wantsEmptyQuery() {
-        return true;
-    }
-
-    private int rescaleHeight(int height) {
-        final WebView current = getCurrentWebview();
-        if (current == null) {
-            return 0;
-        }
-
-        final float scale = current.getScale();
-        if (scale != 0) {
-            return (int) (height / scale);
-        }
-
-        return height;
-    }
-
-    @Override
-    public void onNewDropdownDimensions(int height) {
-        final int rescaledHeight = rescaleHeight(height);
-
-        if (rescaledHeight != mHeight) {
-            mHeight = rescaledHeight;
-            if (mSearchBox != null) {
-                mSearchBox.setDimensions(0, 0, 0, rescaledHeight);
-                mSearchBox.onresize(null);
-            }
-        }
-    }
-
-    private String getInstantBaseUrl() {
-        if (mInstantBaseUrl == null) {
-            String url = mContext.getResources().getString(R.string.instant_base);
-            if (url.indexOf("{CID}") != -1) {
-                url = url.replace("{CID}",
-                        BrowserProvider.getClientId(mContext.getContentResolver()));
-            }
-            mInstantBaseUrl = url;
-        }
-
-        return mInstantBaseUrl;
-    }
-
-    // Indices of the columns in the below arrays.
-    private static final int COLUMN_INDEX_ID = 0;
-    private static final int COLUMN_INDEX_QUERY = 1;
-    private static final int COLUMN_INDEX_ICON = 2;
-    private static final int COLUMN_INDEX_TEXT_1 = 3;
-
-    private static final String[] COLUMNS_WITHOUT_DESCRIPTION = new String[] {
-        "_id",
-        SearchManager.SUGGEST_COLUMN_QUERY,
-        SearchManager.SUGGEST_COLUMN_ICON_1,
-        SearchManager.SUGGEST_COLUMN_TEXT_1,
-    };
-
-    private static class SuggestionsCursor extends AbstractCursor {
-        private final List<String> mSuggestions;
-
-        public SuggestionsCursor(List<String> suggestions) {
-            mSuggestions = suggestions;
-        }
-
-        @Override
-        public int getCount() {
-            return mSuggestions.size();
-        }
-
-        @Override
-        public String[] getColumnNames() {
-            return COLUMNS_WITHOUT_DESCRIPTION;
-        }
-
-        private String format(String suggestion) {
-            if (TextUtils.isEmpty(suggestion)) {
-                return "";
-            }
-            return suggestion;
-        }
-
-        @Override
-        public String getString(int column) {
-            if (mPos >= 0 && mPos < mSuggestions.size()) {
-              if ((column == COLUMN_INDEX_QUERY) || (column == COLUMN_INDEX_TEXT_1)) {
-                  return format(mSuggestions.get(mPos));
-              } else if (column == COLUMN_INDEX_ICON) {
-                  return String.valueOf(R.drawable.magnifying_glass);
-              }
-            }
-            return null;
-        }
-
-        @Override
-        public double getDouble(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public float getFloat(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getInt(int column) {
-            if (column == COLUMN_INDEX_ID) {
-                return mPos;
-            }
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public long getLong(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public short getShort(int column) {
-          throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isNull(int column) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java
index bfdd9a0..659169d 100644
--- a/src/com/android/browser/NavigationBarBase.java
+++ b/src/com/android/browser/NavigationBarBase.java
@@ -22,6 +22,8 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.speech.RecognizerResultsIntent;
+import android.text.Editable;
+import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.View;
@@ -30,15 +32,13 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.browser.UI.DropdownChangeListener;
 import com.android.browser.UrlInputView.UrlInputListener;
-import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
 
 import java.util.List;
 
 public class NavigationBarBase extends LinearLayout implements
         OnClickListener, UrlInputListener, OnFocusChangeListener,
-        TextChangeWatcher {
+        TextWatcher {
 
     protected BaseUi mBaseUi;
     protected TitleBar mTitleBar;
@@ -70,7 +70,7 @@
         mUrlInput.setUrlInputListener(this);
         mUrlInput.setOnFocusChangeListener(this);
         mUrlInput.setSelectAllOnFocus(true);
-        mUrlInput.addQueryTextWatcher(this);
+        mUrlInput.addTextChangedListener(this);
     }
 
     public void setTitleBar(TitleBar titleBar) {
@@ -144,16 +144,6 @@
         }
     }
 
-    // UrlInput text watcher
-
-    @Override
-    public void onTextChanged(String newText) {
-        if (mUrlInput.hasFocus()) {
-            // clear voice mode when user types
-            setInVoiceMode(false, null);
-        }
-    }
-
     // voicesearch
 
     public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
@@ -166,7 +156,7 @@
     }
 
     void clearCompletions() {
-        mUrlInput.setSuggestedText(null);
+        mUrlInput.dismissDropDown();
     }
 
  // UrlInputListener implementation
@@ -250,10 +240,6 @@
         return super.dispatchKeyEventPreIme(evt);
     }
 
-    void registerDropdownChangeListener(DropdownChangeListener d) {
-        mUrlInput.registerDropdownChangeListener(d);
-    }
-
     /**
      * called from the Ui when the user wants to edit
      * @param clearInput clear the input field
@@ -287,4 +273,17 @@
     public void onTabDataChanged(Tab tab) {
     }
 
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        if (mUrlInput.hasFocus()) {
+            // clear voice mode when user types
+            setInVoiceMode(false, null);
+        }
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) { }
 }
diff --git a/src/com/android/browser/NavigationBarTablet.java b/src/com/android/browser/NavigationBarTablet.java
index ef29a49..04f372a 100644
--- a/src/com/android/browser/NavigationBarTablet.java
+++ b/src/com/android/browser/NavigationBarTablet.java
@@ -195,7 +195,7 @@
     }
 
     private void clearOrClose() {
-        if (TextUtils.isEmpty(mUrlInput.getUserText())) {
+        if (TextUtils.isEmpty(mUrlInput.getText())) {
             // close
             mUrlInput.clearFocus();
         } else {
@@ -278,7 +278,7 @@
     }
 
     protected void updateSearchMode(boolean userEdited) {
-        setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText()));
+        setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getText()));
     }
 
     @Override
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
index 15ccfe5..ecab008 100644
--- a/src/com/android/browser/PreferenceKeys.java
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -81,7 +81,6 @@
     // Keys for lab_preferences.xml
     // ----------------------
     static final String PREF_ENABLE_QUICK_CONTROLS = "enable_quick_controls";
-    static final String PREF_USE_INSTANT_SEARCH = "use_instant_search";
     static final String PREF_FULLSCREEN = "fullscreen";
 
     // ----------------------
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index ca3754c..7400b5d 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -563,10 +563,6 @@
 
     }
 
-    private boolean useInstant() {
-        return mSettings.useInstantSearch();
-    }
-
     public void clearCache() {
         mFilterResults = null;
         mSuggestResults = null;
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index a9cbd7b..2bd3754 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -140,11 +140,6 @@
 
     boolean dispatchKey(int code, KeyEvent event);
 
-    public static interface DropdownChangeListener {
-        void onNewDropdownDimensions(int height);
-    }
-    void registerDropdownChangeListener(DropdownChangeListener d);
-
     void showAutoLogin(Tab tab);
 
     void hideAutoLogin(Tab tab);
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index 9b48c46..e7a8953 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -23,7 +23,6 @@
 import android.webkit.WebView;
 
 import com.android.browser.UI.ComboViews;
-import com.android.browser.UI.DropdownChangeListener;
 
 import java.util.List;
 
@@ -92,8 +91,6 @@
 
     void updateMenuState(Tab tab, Menu menu);
 
-    void registerDropdownChangeListener(DropdownChangeListener d);
-
     boolean onOptionsItemSelected(MenuItem item);
 
     SnapshotTab createNewSnapshotTab(long snapshotId, boolean setActive);
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 96ab864..3c0de30 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -19,27 +19,25 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.text.Editable;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.util.Patterns;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.inputmethod.EditorInfo;
 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;
 
 import com.android.browser.SuggestionsAdapter.CompletionListener;
 import com.android.browser.SuggestionsAdapter.SuggestItem;
-import com.android.browser.UI.DropdownChangeListener;
-import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
-import com.android.browser.autocomplete.SuggestiveAutoCompleteTextView;
 import com.android.browser.search.SearchEngine;
 import com.android.browser.search.SearchEngineInfo;
 import com.android.browser.search.SearchEngines;
@@ -51,9 +49,9 @@
  * url/search input view
  * handling suggestions
  */
-public class UrlInputView extends SuggestiveAutoCompleteTextView
+public class UrlInputView extends AutoCompleteTextView
         implements OnEditorActionListener,
-        CompletionListener, OnItemClickListener, TextChangeWatcher {
+        CompletionListener, OnItemClickListener, TextWatcher {
 
     static final String TYPED = "browser-type";
     static final String SUGGESTED = "browser-suggest";
@@ -76,7 +74,6 @@
     private boolean mLandscape;
     private boolean mIncognitoMode;
     private boolean mNeedsUpdate;
-    private DropdownChangeListener mDropdownListener;
 
     private int mState;
     private StateListener mStateListener;
@@ -113,23 +110,8 @@
         setThreshold(1);
         setOnItemClickListener(this);
         mNeedsUpdate = false;
-        mDropdownListener = null;
-        addQueryTextWatcher(this);
+        addTextChangedListener(this);
 
-        mAdapter.registerDataSetObserver(new DataSetObserver() {
-            @Override
-            public void onChanged() {
-                if (!isPopupShowing()) {
-                    return;
-                }
-                dispatchChange();
-            }
-
-            @Override
-            public void onInvalidated() {
-                dispatchChange();
-            }
-        });
         mState = StateListener.STATE_NORMAL;
     }
 
@@ -225,7 +207,7 @@
         mAdapter.setLandscapeMode(mLandscape);
         if (isPopupShowing() && (getVisibility() == View.VISIBLE)) {
             setupDropDown();
-            performFiltering(getUserText(), 0);
+            performFiltering(getText(), 0);
         }
     }
 
@@ -256,21 +238,11 @@
 
     @Override
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-        if (BrowserSettings.getInstance().useInstantSearch() &&
-                (actionId == EditorInfo.IME_ACTION_NEXT)) {
-            // When instant is turned on AND the user chooses to complete
-            // using the tab key, then use the completion rather than the
-            // text that the user has typed.
-            finishInput(getText().toString(), null, TYPED);
-        } else {
-            finishInput(getUserText(), null, TYPED);
-        }
-
+        finishInput(getText().toString(), null, TYPED);
         return true;
     }
 
     void forceFilter() {
-        performForcedFiltering();
         showDropDown();
     }
 
@@ -365,19 +337,6 @@
         return mAdapter;
     }
 
-    private void dispatchChange() {
-        final Rect popupRect = new Rect();
-        getPopupDrawableRect(popupRect);
-
-        if (mDropdownListener != null) {
-            mDropdownListener.onNewDropdownDimensions(popupRect.height());
-        }
-    }
-
-    void registerDropdownChangeListener(DropdownChangeListener d) {
-        mDropdownListener = d;
-    }
-
     /*
      * no-op to prevent scrolling of webview when embedded titlebar
      * gets edited
@@ -388,10 +347,16 @@
     }
 
     @Override
-    public void onTextChanged(String newText) {
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
         if (StateListener.STATE_HIGHLIGHTED == mState) {
             changeState(StateListener.STATE_EDITED);
         }
     }
 
+    @Override
+    public void afterTextChanged(Editable s) { }
+
 }
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index b4afb6f..556e88d 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -130,9 +130,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        if (!BrowserSettings.getInstance().useInstantSearch()) {
-            mNavBar.clearCompletions();
-        }
+        mNavBar.clearCompletions();
     }
 
     @Override
diff --git a/src/com/android/browser/autocomplete/SuggestedSpan.java b/src/com/android/browser/autocomplete/SuggestedSpan.java
deleted file mode 100644
index dc04cb2..0000000
--- a/src/com/android/browser/autocomplete/SuggestedSpan.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.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
deleted file mode 100644
index 95dfcab..0000000
--- a/src/com/android/browser/autocomplete/SuggestedTextController.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.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;
-    private boolean mSuspended = false;
-
-    /**
-     * 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 boolean isCursorHandlingSuspended() {
-        return mSuspended;
-    }
-
-    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);
-        mSuspended = true;
-    }
-
-    /**
-     * 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);
-        }
-        mSuspended = false;
-    }
-
-    /**
-     * 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
deleted file mode 100644
index 50ba758..0000000
--- a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.browser.autocomplete;
-
-import com.android.browser.BrowserSettings;
-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.Html;
-import android.text.Selection;
-import android.text.TextUtils;
-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;
-
-    // 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);
-
-        // The completions are always shown in the same color as the hint
-        // text.
-        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();
-    }
-
-    public 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=" + getUserText().length()
-                + " threshold=" + mThreshold);
-        return getUserText().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 TextChangeWatcher {
-        @Override
-        public void onTextChanged(String newText) {
-            doAfterTextChanged();
-        }
-    }
-
-    /**
-     * @hide
-     */
-    protected void setBlockCompletion(boolean block) {
-        mBlockCompletion = block;
-    }
-
-    void doAfterTextChanged() {
-        if (DEBUG) Log.d(TAG, "doAfterTextChanged(" + getText() + ")");
-        if (mBlockCompletion) 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(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) {
-                performFiltering(null, mLastKeyCode);
-            }
-        }
-    }
-
-    /**
-     * <p>Indicates whether the popup menu is showing.</p>
-     *
-     * @return true if the popup menu is showing, false otherwise
-     */
-    public 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);
-    }
-
-    protected void performForcedFiltering() {
-        boolean wasSuspended = false;
-        if (mController.isCursorHandlingSuspended()) {
-            mController.resumeCursorMovementHandlingAndApplyChanges();
-            wasSuspended = true;
-        }
-
-        mFilter.filter(getUserText().toString(), this);
-
-        if (wasSuspended) {
-            mController.suspendCursorMovementHandling();
-        }
-    }
-
-    /**
-     * <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() &&
-                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);
-                    }
-                });
-            }
-        }
-    }
-
-    public String getUserText() {
-        return mController.getUserText();
-    }
-
-    private void updateText(SuggestionsAdapter adapter) {
-        if (!BrowserSettings.getInstance().useInstantSearch()) {
-            return;
-        }
-
-        if (!isPopupShowing()) {
-            setSuggestedText(null);
-            return;
-        }
-
-        if (mAdapter.getCount() > 0 && !TextUtils.isEmpty(getUserText())) {
-            for (int i = 0; i < mAdapter.getCount(); ++i) {
-                SuggestItem current = mAdapter.getItem(i);
-                if (current.type == SuggestionsAdapter.TYPE_SUGGEST) {
-                    setSuggestedText(current.title);
-                    break;
-                }
-            }
-        }
-    }
-
-    @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);
-            invalidate();
-        }
-    }
-
-    public void setText(CharSequence text, boolean filter) {
-        if (filter) {
-            setText(text);
-        } else {
-            mBlockCompletion = true;
-            // If cursor movement handling was suspended (the view is
-            // not in focus), resume it and apply the pending change.
-            // Since we don't want to perform any filtering, this change
-            // is safe.
-            boolean wasSuspended = false;
-            if (mController.isCursorHandlingSuspended()) {
-                mController.resumeCursorMovementHandlingAndApplyChanges();
-                wasSuspended = true;
-            }
-
-            setText(text);
-
-            if (wasSuspended) {
-                mController.suspendCursorMovementHandling();
-            }
-            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) {
-        if (!TextUtils.isEmpty(text)) {
-            String htmlStripped = Html.fromHtml(text).toString();
-            mController.setSuggestedText(htmlStripped);
-        } else {
-            mController.setSuggestedText(null);
-        }
-    }
-
-    public void getPopupDrawableRect(Rect rect) {
-        if (mPopup.getListView() != null) {
-            mPopup.getListView().getDrawingRect(rect);
-        }
-    }
-}
diff --git a/src/com/android/browser/preferences/LabPreferencesFragment.java b/src/com/android/browser/preferences/LabPreferencesFragment.java
index ca3a86a..222b5fa 100644
--- a/src/com/android/browser/preferences/LabPreferencesFragment.java
+++ b/src/com/android/browser/preferences/LabPreferencesFragment.java
@@ -26,35 +26,11 @@
 import com.android.browser.search.SearchEngine;
 
 public class LabPreferencesFragment extends PreferenceFragment {
-    private BrowserSettings mBrowserSettings;
-    private Preference useInstantPref;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
-        mBrowserSettings = BrowserSettings.getInstance();
-
         // Load the XML preferences file
         addPreferencesFromResource(R.xml.lab_preferences);
-        useInstantPref = findPreference(PreferenceKeys.PREF_USE_INSTANT_SEARCH);
     }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (useInstantPref != null) {
-            useInstantPref.setEnabled(false);
-
-            // Enable the "use instant" preference only if the selected
-            // search engine is google.
-            if (mBrowserSettings.getSearchEngine() != null) {
-                final String currentName = mBrowserSettings.getSearchEngine().getName();
-                if (SearchEngine.GOOGLE.equals(currentName)) {
-                    useInstantPref.setEnabled(true);
-                }
-            }
-        }
-    }
-
 }
diff --git a/src/com/android/browser/search/SearchEngines.java b/src/com/android/browser/search/SearchEngines.java
index fd967f9..433e877 100644
--- a/src/com/android/browser/search/SearchEngines.java
+++ b/src/com/android/browser/search/SearchEngines.java
@@ -15,8 +15,6 @@
  */
 package com.android.browser.search;
 
-import com.android.browser.BrowserSettings;
-import com.android.browser.InstantSearchEngine;
 import com.android.browser.R;
 
 import android.content.Context;
@@ -32,10 +30,6 @@
     private static final String TAG = "SearchEngines";
 
     public static SearchEngine getDefaultSearchEngine(Context context) {
-        if (BrowserSettings.getInstance().useInstantSearch()) {
-            return new InstantSearchEngine(context, DefaultSearchEngine.create(context));
-        }
-
         return DefaultSearchEngine.create(context);
     }
 
diff --git a/tests/src/com/android/browser/autocomplete/SuggestedTextControllerTest.java b/tests/src/com/android/browser/autocomplete/SuggestedTextControllerTest.java
deleted file mode 100644
index f162e3b..0000000
--- a/tests/src/com/android/browser/autocomplete/SuggestedTextControllerTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.browser.autocomplete;
-
-import com.android.browser.autocomplete.SuggestedTextController.TextOwner;
-
-import android.graphics.Color;
-import android.os.Parcelable;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.Editable;
-import android.text.Selection;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.TextWatcher;
-import android.view.AbsSavedState;
-
-/**
- * Test cases for {@link SuggestedTextController}.
- */
-@SmallTest
-public class SuggestedTextControllerTest extends AndroidTestCase {
-
-    // these two must have a common prefix (but not be identical):
-    private static final String RUBY_MURRAY = "ruby murray";
-    private static final String RUBY_TUESDAY = "ruby tuesday";
-    private static final String EXTRA_USER_TEXT = " curry";
-    // no common prefix with the top two above:
-    private static final String TOD_SLOAN = "tod sloan";
-
-    private SuggestedTextController mController;
-    private SpannableStringBuilder mString;
-
-    private SuggestedTextController m2ndController;
-    private SpannableStringBuilder m2ndString;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mString = new SpannableStringBuilder();
-        Selection.setSelection(mString, 0); // position cursor
-        mController = new SuggestedTextController(new BufferTextOwner(mString), Color.GRAY);
-        checkInvariant();
-    }
-
-    private void create2ndController() {
-        m2ndString = new SpannableStringBuilder();
-        Selection.setSelection(m2ndString, 0); // position cursor
-        m2ndController = new SuggestedTextController(new BufferTextOwner(m2ndString), Color.GRAY);
-        check2ndInvariant();
-    }
-
-    private int cursorPos(Spannable string) {
-        int selStart = Selection.getSelectionStart(string);
-        int selEnd = Selection.getSelectionEnd(string);
-        assertEquals("Selection has non-zero length", selStart, selEnd);
-        return selEnd;
-    }
-
-    private int cursorPos() {
-        return cursorPos(mString);
-    }
-
-    private void insertAtCursor(String text) {
-        mString.insert(cursorPos(), text);
-        checkInvariant();
-    }
-
-    private void insertAtCursor(char ch) {
-        insertAtCursor(Character.toString(ch));
-    }
-
-    private void insertAt2ndCursor(String text) {
-        m2ndString.insert(cursorPos(m2ndString), text);
-        check2ndInvariant();
-    }
-
-    private void insertAt2ndCursor(char ch) {
-        insertAt2ndCursor(Character.toString(ch));
-    }
-
-    private void deleteBeforeCursor(int count) {
-        int pos = cursorPos();
-        count = Math.min(pos, count);
-        mString.delete(pos - count, pos);
-        checkInvariant();
-    }
-
-    private void replaceSelection(String withThis) {
-        mString.replace(Selection.getSelectionStart(mString),
-                Selection.getSelectionEnd(mString), withThis);
-        checkInvariant();
-    }
-
-    private void setSuggested(String suggested) {
-        mController.setSuggestedText(suggested);
-        checkInvariant();
-    }
-
-    private void set2ndSuggested(String suggested) {
-        m2ndController.setSuggestedText(suggested);
-        check2ndInvariant();
-    }
-
-    private void checkInvariant() {
-        mController.checkInvariant(mString);
-    }
-
-    private void check2ndInvariant() {
-        m2ndController.checkInvariant(m2ndString);
-    }
-
-    private void assertUserEntered(String expected, SuggestedTextController controller) {
-        assertEquals("User entered text not as expected", expected, controller.getUserText());
-    }
-
-    private void assertUserEntered(String expected) {
-        assertUserEntered(expected, mController);
-    }
-
-    private void assertBuffer(String expected, Editable string) {
-        assertEquals("Buffer contents not as expected", expected, string.toString());
-    }
-
-    private void assertBuffer(String expected) {
-        assertBuffer(expected, mString);
-    }
-
-    private void assertCursorPos(int where, Spannable string) {
-        assertEquals("Cursor not at expected position", where, cursorPos(string));
-    }
-
-    private void assertCursorPos(int where) {
-        assertCursorPos(where, mString);
-    }
-
-    private static final String commonPrefix(String a, String b) {
-        int pos = 0;
-        while (a.charAt(pos) == b.charAt(pos)) {
-            pos++;
-        }
-        assertTrue("No common prefix between '" + a + "' and '" + b + "'", pos > 0);
-        return a.substring(0, pos);
-    }
-
-    public void testTypeNoSuggested() {
-        for (int i = 0; i < RUBY_MURRAY.length(); ++i) {
-            assertCursorPos(i);
-            assertUserEntered(RUBY_MURRAY.substring(0, i));
-            assertBuffer(RUBY_MURRAY.substring(0, i));
-            insertAtCursor(RUBY_MURRAY.substring(i, i + 1));
-        }
-    }
-
-    public void testTypeSuggested() {
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(0);
-        assertBuffer(RUBY_MURRAY);
-        for (int i = 0; i < RUBY_MURRAY.length(); ++i) {
-            assertCursorPos(i);
-            assertUserEntered(RUBY_MURRAY.substring(0, i));
-            assertBuffer(RUBY_MURRAY);
-            insertAtCursor(RUBY_MURRAY.charAt(i));
-        }
-    }
-
-    public void testSetSuggestedAfterTextEntry() {
-        final int count = RUBY_MURRAY.length() / 2;
-        for (int i = 0; i < count; ++i) {
-            assertCursorPos(i);
-            assertUserEntered(RUBY_MURRAY.substring(0, i));
-            insertAtCursor(RUBY_MURRAY.substring(i, i + 1));
-        }
-        setSuggested(RUBY_MURRAY);
-        assertUserEntered(RUBY_MURRAY.substring(0, count));
-        assertBuffer(RUBY_MURRAY);
-    }
-
-    public void testTypeSuggestedUpperCase() {
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(0);
-        for (int i = 0; i < RUBY_MURRAY.length(); ++i) {
-            assertCursorPos(i);
-            assertUserEntered(RUBY_MURRAY.substring(0, i).toUpperCase());
-            assertTrue("Buffer doesn't contain suggested text",
-                    RUBY_MURRAY.equalsIgnoreCase(mString.toString()));
-            insertAtCursor(Character.toUpperCase(RUBY_MURRAY.charAt(i)));
-        }
-    }
-
-    public void testChangeSuggestedText() {
-        String pref = commonPrefix(RUBY_MURRAY, RUBY_TUESDAY);
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(pref);
-        assertBuffer(RUBY_MURRAY);
-        assertUserEntered(pref);
-        setSuggested(RUBY_TUESDAY);
-        assertBuffer(RUBY_TUESDAY);
-        assertUserEntered(pref);
-    }
-
-    public void testTypeNonSuggested() {
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_MURRAY.charAt(0));
-        assertBuffer(RUBY_MURRAY);
-        insertAtCursor('x');
-        assertBuffer("rx");
-    }
-
-    public void testTypeNonSuggestedThenNewSuggestion() {
-        final String pref = commonPrefix(RUBY_MURRAY, RUBY_TUESDAY);
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(0);
-        insertAtCursor(pref);
-        assertCursorPos(pref.length());
-        assertUserEntered(pref);
-        insertAtCursor(RUBY_TUESDAY.charAt(pref.length()));
-        assertBuffer(RUBY_TUESDAY.substring(0, pref.length() + 1));
-        setSuggested(RUBY_TUESDAY);
-        assertBuffer(RUBY_TUESDAY);
-    }
-
-    public void testChangeSuggestedToNonUserEntered() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(half);
-        setSuggested(TOD_SLOAN);
-        assertUserEntered(half);
-        assertBuffer(half);
-    }
-
-    public void testChangeSuggestedToUserEntered() {
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(TOD_SLOAN);
-        setSuggested(TOD_SLOAN);
-        assertUserEntered(TOD_SLOAN);
-        assertBuffer(TOD_SLOAN);
-    }
-
-    public void testChangeSuggestedToEmpty() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(half);
-        setSuggested(null);
-        assertUserEntered(half);
-        assertBuffer(half);
-    }
-
-    public void testChangeSuggestedToEmptyFromUserEntered() {
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_MURRAY);
-        setSuggested(null);
-        assertUserEntered(RUBY_MURRAY);
-        assertBuffer(RUBY_MURRAY);
-    }
-
-    public void typeNonSuggestedThenDelete() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        assertCursorPos(0);
-        insertAtCursor(half);
-        assertCursorPos(half.length());
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor('x');
-        assertBuffer(half + "x");
-        deleteBeforeCursor(1);
-        assertUserEntered(half);
-        assertBuffer(RUBY_MURRAY);
-    }
-
-    public void testDeleteMultipleFromSuggested() {
-        final String twoThirds = RUBY_MURRAY.substring(0, (RUBY_MURRAY.length() * 2) / 3);
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(twoThirds);
-        assertCursorPos(twoThirds.length());
-        // select some of the text just entered:
-        Selection.setSelection(mString, RUBY_MURRAY.length() / 3, twoThirds.length());
-        // and delete it:
-        replaceSelection("");
-        assertCursorPos(RUBY_MURRAY.length() / 3);
-        assertUserEntered(RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 3));
-        assertBuffer(RUBY_MURRAY);
-    }
-
-    public void testDeleteMultipleToFormSuggested() {
-        final String pref = commonPrefix(RUBY_TUESDAY, RUBY_MURRAY);
-        final int extra = (RUBY_TUESDAY.length() - pref.length()) / 2;
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_TUESDAY.substring(0, pref.length() + extra));
-        assertCursorPos(pref.length() + extra);
-        // select and delete extra characters, leaving just prefix
-        Selection.setSelection(mString, pref.length(), pref.length() + extra);
-        replaceSelection("");
-        assertCursorPos(pref.length());
-        assertBuffer(RUBY_MURRAY);
-        assertUserEntered(pref);
-    }
-
-    public void testBackspaceWithinUserTextFromSuggested() {
-        StringBuffer half = new StringBuffer(RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2));
-        insertAtCursor(half.toString());
-        int backSpaceFrom = half.length() / 2;
-        Selection.setSelection(mString, backSpaceFrom);
-        deleteBeforeCursor(1);
-        assertCursorPos(backSpaceFrom - 1);
-        half.delete(backSpaceFrom - 1, backSpaceFrom);
-        assertUserEntered(half.toString());
-        assertBuffer(half.toString());
-    }
-
-    public void testInsertWithinUserTextToFormSuggested() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        StringBuffer initial = new StringBuffer(half);
-        int pos = initial.length() / 2;
-        char toInsert = initial.charAt(pos);
-        initial.delete(pos, pos + 1);
-        insertAtCursor(initial.toString());
-        setSuggested(RUBY_MURRAY);
-        assertUserEntered(initial.toString());
-        assertBuffer(initial.toString());
-        Selection.setSelection(mString, pos);
-        insertAtCursor(toInsert);
-        assertCursorPos(pos + 1);
-        assertUserEntered(half);
-        assertBuffer(RUBY_MURRAY);
-    }
-
-    public void testEnterTextBeyondSuggested() {
-        setSuggested(RUBY_MURRAY);
-        int i = RUBY_MURRAY.length() / 2;
-        insertAtCursor(RUBY_MURRAY.substring(0, i));
-        String query = RUBY_MURRAY + EXTRA_USER_TEXT;
-        for (; i < query.length(); ++i) {
-            assertUserEntered(query.substring(0, i));
-            if (i <= RUBY_MURRAY.length()) {
-                assertBuffer(RUBY_MURRAY);
-            }
-            insertAtCursor(query.charAt(i));
-        }
-        assertUserEntered(query);
-    }
-
-    public void testDeleteFromLongerThanSuggested() {
-        setSuggested(RUBY_MURRAY);
-        final String entered = RUBY_MURRAY + EXTRA_USER_TEXT;
-        insertAtCursor(entered);
-        for (int i = entered.length(); i > (RUBY_MURRAY.length() / 2); --i) {
-            assertCursorPos(i);
-            assertUserEntered(entered.substring(0, i));
-            if (i <= RUBY_MURRAY.length()) {
-                assertBuffer(RUBY_MURRAY);
-            }
-            deleteBeforeCursor(1);
-        }
-    }
-
-    public void testReplaceWithShorterToFormSuggested() {
-        final String pref = commonPrefix(RUBY_TUESDAY, RUBY_MURRAY);
-        final int extra = (RUBY_TUESDAY.length() - pref.length()) / 2;
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_TUESDAY.substring(0, pref.length() + extra));
-        assertCursorPos(pref.length() + extra);
-        // select and replace extra characters, to match suggested
-        Selection.setSelection(mString, pref.length(), pref.length() + extra);
-        replaceSelection(RUBY_MURRAY.substring(pref.length(), pref.length() + extra - 1));
-        assertBuffer(RUBY_MURRAY);
-        assertUserEntered(RUBY_MURRAY.substring(0, pref.length() + extra - 1));
-    }
-
-    public void testReplaceWithSameLengthToFormSuggested() {
-        final String pref = commonPrefix(RUBY_TUESDAY, RUBY_MURRAY);
-        final int extra = (RUBY_TUESDAY.length() - pref.length()) / 2;
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_TUESDAY.substring(0, pref.length() + extra));
-        assertCursorPos(pref.length() + extra);
-        // select and replace extra characters, to match suggested
-        Selection.setSelection(mString, pref.length(), pref.length() + extra);
-        replaceSelection(RUBY_MURRAY.substring(pref.length(), pref.length() + extra));
-        assertBuffer(RUBY_MURRAY);
-        assertUserEntered(RUBY_MURRAY.substring(0, pref.length() + extra));
-    }
-
-    public void testReplaceWithLongerToFormSuggested() {
-        final String pref = commonPrefix(RUBY_TUESDAY, RUBY_MURRAY);
-        final int extra = (RUBY_TUESDAY.length() - pref.length()) / 2;
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(RUBY_TUESDAY.substring(0, pref.length() + extra));
-        assertCursorPos(pref.length() + extra);
-        // select and replace extra characters, to match suggested
-        Selection.setSelection(mString, pref.length(), pref.length() + extra);
-        replaceSelection(RUBY_MURRAY.substring(pref.length(), pref.length() + extra + 1));
-        assertBuffer(RUBY_MURRAY);
-        assertUserEntered(RUBY_MURRAY.substring(0, pref.length() + extra + 1));
-    }
-
-    public void testMoveCursorIntoSuggested() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        insertAtCursor(half);
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(half.length());
-        Selection.setSelection(mString, half.length() + 1);
-        checkInvariant();
-        assertUserEntered(RUBY_MURRAY);
-    }
-
-    public void testMoveCursorWithinUserEntered() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        insertAtCursor(half);
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(half.length());
-        Selection.setSelection(mString, half.length() - 1);
-        checkInvariant();
-        assertUserEntered(half);
-    }
-
-    public void testSelectWithinSuggested() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        insertAtCursor(half);
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(half.length());
-        Selection.setSelection(mString, half.length() + 1, half.length() + 2);
-        checkInvariant();
-        assertUserEntered(RUBY_MURRAY);
-    }
-
-    public void testSelectStraddlingSuggested() {
-        final String half = RUBY_MURRAY.substring(0, RUBY_MURRAY.length() / 2);
-        insertAtCursor(half);
-        setSuggested(RUBY_MURRAY);
-        assertCursorPos(half.length());
-        Selection.setSelection(mString, half.length() - 1, half.length() + 1);
-        checkInvariant();
-        assertUserEntered(RUBY_MURRAY);
-    }
-
-    public void testSaveAndRestoreNoText() {
-        create2ndController();
-        Parcelable state = mController.saveInstanceState(AbsSavedState.EMPTY_STATE);
-        m2ndController.restoreInstanceState(state);
-        check2ndInvariant();
-        assertBuffer("", m2ndString);
-    }
-
-    public void testSaveAndRestoreWithSuggestedText() {
-        create2ndController();
-        setSuggested(TOD_SLOAN);
-        Parcelable state = mController.saveInstanceState(AbsSavedState.EMPTY_STATE);
-        m2ndController.restoreInstanceState(state);
-        check2ndInvariant();
-        assertBuffer(TOD_SLOAN, m2ndString);
-        assertUserEntered("", m2ndController);
-    }
-
-    public void testSaveAndRestoreWithUserEnteredAndSuggestedText() {
-        final String half = TOD_SLOAN.substring(0, TOD_SLOAN.length() / 2);
-        create2ndController();
-        setSuggested(TOD_SLOAN);
-        insertAtCursor(half);
-        Parcelable state = mController.saveInstanceState(AbsSavedState.EMPTY_STATE);
-        m2ndController.restoreInstanceState(state);
-        check2ndInvariant();
-        assertBuffer(TOD_SLOAN, m2ndString);
-        assertUserEntered(half, m2ndController);
-        assertCursorPos(half.length(), m2ndString);
-    }
-
-    public void testSaveAndRestoreWithNonSuggested() {
-        final String half = TOD_SLOAN.substring(0, TOD_SLOAN.length() / 2);
-        create2ndController();
-        setSuggested(RUBY_MURRAY);
-        insertAtCursor(half);
-        Parcelable state = mController.saveInstanceState(AbsSavedState.EMPTY_STATE);
-        m2ndController.restoreInstanceState(state);
-        check2ndInvariant();
-        assertBuffer(half, m2ndString);
-        assertUserEntered(half, m2ndController);
-        assertCursorPos(half.length(), m2ndString);
-    }
-
-    public void testSaveAndRestoreThenTypeSuggested() {
-        final String half = TOD_SLOAN.substring(0, TOD_SLOAN.length() / 2);
-        create2ndController();
-        set2ndSuggested(TOD_SLOAN);
-        insertAt2ndCursor(half);
-        insertAt2ndCursor('x');
-        Parcelable state = m2ndController.saveInstanceState(AbsSavedState.EMPTY_STATE);
-        mController.restoreInstanceState(state);
-        assertCursorPos(half.length() + 1);
-        // delete the x
-        deleteBeforeCursor(1);
-        assertCursorPos(half.length());
-        assertBuffer(TOD_SLOAN);
-        assertUserEntered(half);
-    }
-
-    public void testSuspendAndResumeCursorProcessing() {
-        final String half = TOD_SLOAN.substring(0, TOD_SLOAN.length() / 2);
-        setSuggested(TOD_SLOAN);
-        insertAtCursor(half);
-        mController.suspendCursorMovementHandling();
-        Selection.setSelection(mString, TOD_SLOAN.length());
-        Selection.setSelection(mString, half.length());
-        mController.resumeCursorMovementHandlingAndApplyChanges();
-        assertCursorPos(half.length());
-        assertUserEntered(half);
-        assertBuffer(TOD_SLOAN);
-    }
-
-    private static class BufferTextOwner implements TextOwner {
-
-        private final Editable mBuffer;
-
-        public BufferTextOwner(Editable buffer) {
-            mBuffer = buffer;
-        }
-
-        public void addTextChangedListener(TextWatcher watcher) {
-            mBuffer.setSpan(watcher , 0, mBuffer.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-        }
-
-        public void removeTextChangedListener(TextWatcher watcher) {
-            mBuffer.removeSpan(watcher);
-        }
-
-        public Editable getText() {
-            return mBuffer;
-        }
-
-        public void setText(String text) {
-            mBuffer.replace(0, mBuffer.length(), text);
-        }
-
-    }
-
-}
