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);
     }
 
