diff --git a/src/com/android/launcher/Launcher.java b/src/com/android/launcher/Launcher.java
index 7dd3418..3bf96aa 100644
--- a/src/com/android/launcher/Launcher.java
+++ b/src/com/android/launcher/Launcher.java
@@ -20,6 +20,7 @@
 import android.app.AlertDialog;
 import android.app.Application;
 import android.app.Dialog;
+import android.app.IWallpaperService;
 import android.app.SearchManager;
 import android.app.StatusBarManager;
 import android.content.ActivityNotFoundException;
@@ -35,26 +36,24 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Message;
 import android.os.MessageQueue;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.Message;
-import android.provider.*;
-import android.telephony.PhoneNumberUtils;
+import android.provider.LiveFolders;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -71,11 +70,11 @@
 import android.view.View.OnLongClickListener;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
+import android.widget.GridView;
+import android.widget.ListView;
+import android.widget.SlidingDrawer;
 import android.widget.TextView;
 import android.widget.Toast;
-import android.widget.GridView;
-import android.widget.SlidingDrawer;
-import android.app.IWallpaperService;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 
@@ -168,7 +167,6 @@
 
     private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
     private final ContentObserver mObserver = new FavoritesChangeObserver();
-    private final ContentObserver mAppWidgetResetObserver = new AppWidgetResetObserver();
 
     private LayoutInflater mInflater;
 
@@ -353,6 +351,9 @@
         if (mRestoring) {
             startLoaders();
         }
+
+        // Make sure that the search gadget (if any) is in its normal place.
+        stopSearch(false);
     }
 
     @Override
@@ -387,45 +388,29 @@
             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,
                     keyCode, event);
             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {
-                // something usable has been typed - dispatch it now.
-                final String str = mDefaultKeySsb.toString();
-
-                boolean isDialable = true;
-                final int count = str.length();
-                for (int i = 0; i < count; i++) {
-                    if (!PhoneNumberUtils.isReallyDialable(str.charAt(i))) {
-                        isDialable = false;
-                        break;
-                    }
-                }
-                Intent intent;
-                if (isDialable) {
-                    intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", str, null));
-                } else {
-                    intent = new Intent(Contacts.Intents.UI.FILTER_CONTACTS_ACTION);
-                    intent.putExtra(Contacts.Intents.UI.FILTER_TEXT_EXTRA_KEY, str);
-                }
-
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
-                try {
-                    startActivity(intent);
-                } catch (android.content.ActivityNotFoundException ex) {
-                    // Oh well... no one knows how to filter/dial. Life goes on.
-                }
-
-                mDefaultKeySsb.clear();
-                mDefaultKeySsb.clearSpans();
-                Selection.setSelection(mDefaultKeySsb, 0);
-
-                return true;
+                // something usable has been typed - start a search
+                // the typed text will be retrieved and cleared by 
+                // showSearchDialog()
+                // If there are multiple keystrokes before the search dialog takes focus,
+                // onSearchRequested() will be called for every keystroke,
+                // but it is idempotent, so it's fine.
+                return onSearchRequested();
             }
         }
 
         return handled;
     }
 
+    private String getTypedText() {
+        return mDefaultKeySsb.toString();
+    }
+
+    private void clearTypedText() {
+        mDefaultKeySsb.clear();
+        mDefaultKeySsb.clearSpans();
+        Selection.setSelection(mDefaultKeySsb, 0);
+    }
+
     /**
      * Restores the previous state, if it exists.
      *
@@ -495,7 +480,7 @@
         drawer.setOnDrawerCloseListener(drawerManager);
         drawer.setOnDrawerScrollListener(drawerManager);
 
-        grid.setTextFilterEnabled(true);
+        grid.setTextFilterEnabled(false);
         grid.setDragger(dragLayer);
         grid.setLauncher(this);
 
@@ -827,7 +812,6 @@
         sModel.abortLoaders();
 
         getContentResolver().unregisterContentObserver(mObserver);
-        getContentResolver().unregisterContentObserver(mAppWidgetResetObserver);
         unregisterReceiver(mApplicationsReceiver);
     }
 
@@ -840,13 +824,76 @@
     @Override
     public void startSearch(String initialQuery, boolean selectInitialQuery, 
             Bundle appSearchData, boolean globalSearch) {
+
+        closeDrawer(false);
+        
+        // Slide the search widget to the top, if it's on the current screen,
+        // otherwise show the search dialog immediately.
+        Search searchWidget = mWorkspace.findSearchWidgetOnCurrentScreen();
+        if (searchWidget == null) {
+            showSearchDialog(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+        } else {
+            searchWidget.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+            // show the currently typed text in the search widget while sliding
+            searchWidget.setQuery(getTypedText());
+        }
+    }
+    
+    /**
+     * Show the search dialog immediately, without changing the search widget.
+     * See {@link Activity.startSearch()} for the arguments.
+     */
+    public void showSearchDialog(String initialQuery, boolean selectInitialQuery, 
+            Bundle appSearchData, boolean globalSearch) {
+        
+        if (initialQuery == null) {
+            // Use any text typed in the launcher as the initial query
+            initialQuery = getTypedText();
+            clearTypedText();
+        }
         if (appSearchData == null) {
             appSearchData = new Bundle();
             appSearchData.putString(SearchManager.SOURCE, "launcher-search");
         }
-        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+        
+        final SearchManager searchManager =
+                (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+
+        final Search searchWidget = mWorkspace.findSearchWidgetOnCurrentScreen();
+        if (searchWidget != null) {
+            // This gets called when the user leaves the search dialog to go back to
+            // the Launcher.
+            searchManager.setOnCancelListener(new SearchManager.OnCancelListener() {
+                public void onCancel() {
+                    searchManager.setOnCancelListener(null);
+                    stopSearch(true);
+                }            
+            });
+        }
+        
+        searchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
+            appSearchData, globalSearch); 
     }
 
+    /**
+     * Cancel search dialog if it is open.
+     * 
+     * @param animate Whether to animate the search gadget (if any) when restoring it
+     * to its original position.
+     */
+    public void stopSearch(boolean animate) {
+        // Close search dialog
+        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        if (searchManager.isVisible()) {
+            searchManager.stopSearch();
+        }
+        // Restore search widget to its normal position
+        Search searchWidget = mWorkspace.findSearchWidgetOnCurrentScreen();
+        if (searchWidget != null) {
+            searchWidget.stopSearch(false);
+        }
+    }
+    
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         if (mDesktopLocked) return false;
@@ -905,15 +952,16 @@
 
         return super.onOptionsItemSelected(item);
     }
+    
+    /**
+     * Indicates that we want global search for this activity by setting the globalSearch
+     * argument for {@link #startSearch} to true.
+     */
 
     @Override
     public boolean onSearchRequested() {
-        if (mWorkspace.snapToSearch()) {
-            closeDrawer(true);                // search widget: get drawer out of the way
-            return true;
-        } else {
-            return super.onSearchRequested(); // no search widget: use system search UI
-        }
+        startSearch(null, false, null, true); 
+        return true;
     }
 
     private void addItems() {
@@ -975,6 +1023,8 @@
     
         final View view = mInflater.inflate(info.layoutResource, null);
         view.setTag(info);
+        Search search = (Search) view.findViewById(R.id.widget_search);
+        search.setLauncher(this);
     
         mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY);
     }
@@ -1158,7 +1208,6 @@
     private void registerContentObservers() {
         ContentResolver resolver = getContentResolver();
         resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
-        resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI, true, mAppWidgetResetObserver);
     }
 
     @Override
@@ -1224,16 +1273,6 @@
         sModel.loadUserItems(false, this, false, false);
     }
 
-    /**
-     * When reset, we handle by calling {@link AppWidgetHost#startListening()}
-     * to make sure our callbacks are set correctly.
-     */
-    private void onAppWidgetReset() {
-        if (mAppWidgetHost != null) {
-            mAppWidgetHost.startListening();
-        }
-    }
-
     void onDesktopItemsLoaded() {
         if (mDestroyed) return;
         bindDesktopItems();
@@ -1250,8 +1289,6 @@
             return;
         }
 
-        mAllAppsGrid.setAdapter(drawerAdapter);
-
         final Workspace workspace = mWorkspace;
         int count = workspace.getChildCount();
         for (int i = 0; i < count; i++) {
@@ -1275,7 +1312,7 @@
             mBinder.mTerminate = true;
         }
         
-        mBinder = new DesktopBinder(this, shortcuts, appWidgets);
+        mBinder = new DesktopBinder(this, shortcuts, appWidgets, drawerAdapter);
         mBinder.startBindingItems();
     }
 
@@ -1317,6 +1354,9 @@
                     final View view = mInflater.inflate(R.layout.widget_search,
                             (ViewGroup) workspace.getChildAt(screen), false);
                     
+                    Search search = (Search) view.findViewById(R.id.widget_search);
+                    search.setLauncher(this);
+                    
                     final Widget widget = (Widget) item;
                     view.setTag(widget);
                     
@@ -1329,7 +1369,7 @@
 
         if (end >= count) {
             finishBindDesktopItems();
-            binder.startBindingAppWidgetsWhenIdle();
+            binder.startBindingDrawer();
         } else {
             binder.obtainMessage(DesktopBinder.MESSAGE_BIND_ITEMS, i, count).sendToTarget();
         }
@@ -1376,6 +1416,12 @@
         mDrawer.unlock();
     }
     
+    private void bindDrawer(Launcher.DesktopBinder binder,
+            ApplicationsAdapter drawerAdapter) {
+        mAllAppsGrid.setAdapter(drawerAdapter);
+        binder.startBindingAppWidgetsWhenIdle();
+    }
+    
     private void bindAppWidgets(Launcher.DesktopBinder binder,
             LinkedList<LauncherAppWidgetInfo> appWidgets) {
         
@@ -1386,14 +1432,10 @@
             final LauncherAppWidgetInfo item = appWidgets.removeFirst();
             
             final int appWidgetId = item.appWidgetId;
-            final AppWidgetProviderInfo appWidgetInfo =
-                    mAppWidgetManager.getAppWidgetInfo(appWidgetId);
+            final AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
             
-            if (LOGD) {
-                d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s",
-                        appWidgetId, appWidgetInfo));
-            }
+            if (LOGD) d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s", appWidgetId, appWidgetInfo));
             
             item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
             item.hostView.setTag(item);
@@ -1891,21 +1933,6 @@
     }
 
     /**
-     * Receives notifications when the {@link AppWidgetHost} has been reset,
-     * usually only when the {@link LauncherProvider} database is first created.
-     */
-    private class AppWidgetResetObserver extends ContentObserver {
-        public AppWidgetResetObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            onAppWidgetReset();
-        }
-    }
-
-    /**
      * Receives intents from other applications to change the wallpaper.
      */
     private static class WallpaperIntentReceiver extends BroadcastReceiver {
@@ -1996,21 +2023,25 @@
     private static class DesktopBinder extends Handler implements MessageQueue.IdleHandler {
         static final int MESSAGE_BIND_ITEMS = 0x1;
         static final int MESSAGE_BIND_APPWIDGETS = 0x2;
+        static final int MESSAGE_BIND_DRAWER = 0x3;
         
         // Number of items to bind in every pass
         static final int ITEMS_COUNT = 6;
 
         private final ArrayList<ItemInfo> mShortcuts;
         private final LinkedList<LauncherAppWidgetInfo> mAppWidgets;
+        private final ApplicationsAdapter mDrawerAdapter;
         private final WeakReference<Launcher> mLauncher;
         
-        public volatile boolean mTerminate = false;
+        public boolean mTerminate = false;
 
         DesktopBinder(Launcher launcher, ArrayList<ItemInfo> shortcuts,
-                ArrayList<LauncherAppWidgetInfo> appWidgets) {
+                ArrayList<LauncherAppWidgetInfo> appWidgets,
+                ApplicationsAdapter drawerAdapter) {
 
             mLauncher = new WeakReference<Launcher>(launcher);
             mShortcuts = shortcuts;
+            mDrawerAdapter = drawerAdapter;
             
             // Sort widgets so active workspace is bound first
             final int currentScreen = launcher.mWorkspace.getCurrentScreen();
@@ -2030,6 +2061,10 @@
         public void startBindingItems() {
             obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts.size()).sendToTarget();
         }
+
+        public void startBindingDrawer() {
+            obtainMessage(MESSAGE_BIND_DRAWER).sendToTarget();
+        }
         
         public void startBindingAppWidgetsWhenIdle() {
             // Ask for notification when message queue becomes idle
@@ -2059,6 +2094,10 @@
                     launcher.bindItems(this, mShortcuts, msg.arg1, msg.arg2);
                     break;
                 }
+                case MESSAGE_BIND_DRAWER: {
+                    launcher.bindDrawer(this, mDrawerAdapter);
+                    break;
+                }
                 case MESSAGE_BIND_APPWIDGETS: {
                     launcher.bindAppWidgets(this, mAppWidgets);
                     break;
@@ -2067,3 +2106,4 @@
         }
     }
 }
+
diff --git a/src/com/android/launcher/Search.java b/src/com/android/launcher/Search.java
index 71ab7ef..3d09479 100644
--- a/src/com/android/launcher/Search.java
+++ b/src/com/android/launcher/Search.java
@@ -16,71 +16,59 @@
 
 package com.android.launcher;
 
-import android.app.ISearchManager;
-import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.database.Cursor;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
+import android.content.res.Configuration;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.server.search.SearchableInfo;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.view.View.OnKeyListener;
 import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AutoCompleteTextView;
-import android.widget.CursorAdapter;
-import android.widget.Filter;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.Interpolator;
+import android.view.animation.Transformation;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.ImageButton;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
 
-public class Search extends LinearLayout implements OnClickListener, OnKeyListener,
-        OnLongClickListener, TextWatcher, OnItemClickListener, OnItemSelectedListener {
+public class Search extends LinearLayout 
+        implements OnClickListener, OnKeyListener, OnLongClickListener {
+
+    // Speed at which the widget slides up/down, in pixels/ms.
+    private static final float ANIMATION_VELOCITY = 1.0f;
 
     private final String TAG = "SearchWidget";
 
-    private AutoCompleteTextView mSearchText;
-    private ImageButton mGoButton;
+    private Launcher mLauncher;
+
+    private TextView mSearchText;
     private ImageButton mVoiceButton;
-    private OnLongClickListener mLongClickListener;
-    
-    // Support for suggestions
-    private SuggestionsAdapter mSuggestionsAdapter;
-    private SearchableInfo mSearchable;
-    private String mSuggestionAction = null;
-    private Uri mSuggestionData = null;
-    private String mSuggestionQuery = null;
-    private int mItemSelected = -1;
-    
+
+    /** The animation that morphs the search widget to the search dialog. */
+    private Animation mMorphAnimation;
+
+    /** The animation that morphs the search widget back to its normal position. */
+    private Animation mUnmorphAnimation;
+
+    // These four are passed to Launcher.startSearch() when the search widget
+    // has finished morphing. They are instance variables to make it possible to update
+    // them while the widget is morphing.
+    private String mInitialQuery;
+    private boolean mSelectInitialQuery;    
+    private Bundle mAppSearchData;
+    private boolean mGlobalSearch;
+
     // For voice searching
     private Intent mVoiceSearchIntent;
 
-    private Rect mTempRect = new Rect();
-    private boolean mRestoreFocus = false;
-
     /**
      * Used to inflate the Workspace from XML.
      *
@@ -89,293 +77,235 @@
      */
     public Search(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        Interpolator interpolator = new AccelerateDecelerateInterpolator();
+
+        mMorphAnimation = new ToParentOriginAnimation();
+        // no need to apply transformation before the animation starts,
+        // since the gadget is already in its normal place.
+        mMorphAnimation.setFillBefore(false);
+        // stay in the top position after the animation finishes
+        mMorphAnimation.setFillAfter(true);
+        mMorphAnimation.setInterpolator(interpolator);
+        mMorphAnimation.setAnimationListener(new Animation.AnimationListener() {
+            // The amount of time before the animation ends to show the search dialog.
+            private static final long TIME_BEFORE_ANIMATION_END = 80;
+            
+            // The runnable which we'll pass to our handler to show the search dialog.
+            private final Runnable mShowSearchDialogRunnable = new Runnable() {
+                public void run() {
+                    showSearchDialog();
+                }
+            };
+            
+            public void onAnimationEnd(Animation animation) { }
+            public void onAnimationRepeat(Animation animation) { }
+            public void onAnimationStart(Animation animation) {
+                // Make the search dialog show up ideally *just* as the animation reaches
+                // the top, to aid the illusion that the widget becomes the search dialog.
+                // Otherwise, there is a short delay when the widget reaches the top before
+                // the search dialog shows. We do this roughly 80ms before the animation ends.
+                getHandler().postDelayed(
+                        mShowSearchDialogRunnable,
+                        Math.max(mMorphAnimation.getDuration() - TIME_BEFORE_ANIMATION_END, 0));
+            }
+        });
+
+        mUnmorphAnimation = new FromParentOriginAnimation();
+        // stay in the top position until the animation starts
+        mUnmorphAnimation.setFillBefore(true);
+        // no need to apply transformation after the animation finishes,
+        // since the gadget is now back in its normal place.
+        mUnmorphAnimation.setFillAfter(false);
+        mUnmorphAnimation.setInterpolator(interpolator);
+        mUnmorphAnimation.setAnimationListener(new Animation.AnimationListener(){
+            public void onAnimationEnd(Animation animation) {
+                clearAnimation();
+            }
+            public void onAnimationRepeat(Animation animation) { }
+            public void onAnimationStart(Animation animation) { }
+        });
         
         mVoiceSearchIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
         mVoiceSearchIntent.putExtra(android.speech.RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                 android.speech.RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
     }
-    
+
     /**
-     * Implements OnClickListener (for button)
+     * Implements OnClickListener.
      */
     public void onClick(View v) {
-        if (v == mGoButton) {
-            query();
-        } else if (v == mVoiceButton) {
-            try {
-                getContext().startActivity(mVoiceSearchIntent);
-            } catch (ActivityNotFoundException ex) {
-                // Should not happen, since we check the availability of
-                // voice search before showing the button. But just in case...
-                Log.w(TAG, "Could not find voice search activity");
+        if (v == mVoiceButton) {
+            startVoiceSearch();
+        } else {
+            mLauncher.onSearchRequested();
+        }
+    }
+
+    private void startVoiceSearch() {
+        try {
+            getContext().startActivity(mVoiceSearchIntent);
+        } catch (ActivityNotFoundException ex) {
+            // Should not happen, since we check the availability of
+            // voice search before showing the button. But just in case...
+            Log.w(TAG, "Could not find voice search activity");
+        }
+    }
+
+    /**
+     * Sets the query text. The query field is not editable, instead we forward
+     * the key events to the launcher, which keeps track of the text, 
+     * calls setQuery() to show it, and gives it to the search dialog.
+     */
+    public void setQuery(String query) {
+        mSearchText.setText(query, TextView.BufferType.NORMAL);
+    }
+
+    /**
+     * Morph the search gadget to the search dialog.
+     * See {@link Activity.startSearch()} for the arguments.
+     */
+    public void startSearch(String initialQuery, boolean selectInitialQuery, 
+            Bundle appSearchData, boolean globalSearch) {
+        mInitialQuery = initialQuery;
+        mSelectInitialQuery = selectInitialQuery;
+        mAppSearchData = appSearchData;
+        mGlobalSearch = globalSearch;
+        
+        // Call up the keyboard before we actually call the search dialog so that it
+        // (hopefully) animates in at about the same time as the widget animation, and
+        // so that it becomes available as soon as possible. Only do this if a hard
+        // keyboard is not currently available.
+        if (getContext().getResources().getConfiguration().hardKeyboardHidden ==
+                Configuration.HARDKEYBOARDHIDDEN_YES) {
+            // Make sure the text field is not focusable, so it's not responsible for
+            // causing the whole view to shift up to accommodate the keyboard.
+            mSearchText.setFocusable(false);
+            
+            InputMethodManager inputManager = (InputMethodManager)
+                    getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+            inputManager.showSoftInputUnchecked(0, null);
+        }
+        
+        if (isAtTop()) {
+            showSearchDialog();
+        } else {
+            // Start the animation, unless it has already started.
+            if (getAnimation() != mMorphAnimation) {
+                mMorphAnimation.setDuration(getAnimationDuration());
+                startAnimation(mMorphAnimation);
             }
         }
     }
 
-    private void query() {
-        String query = mSearchText.getText().toString();
-        if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) {
-            return;
+    /**
+     * Shows the system search dialog immediately, without any animation.
+     */
+    private void showSearchDialog() {
+        mLauncher.showSearchDialog(
+                mInitialQuery, mSelectInitialQuery, mAppSearchData, mGlobalSearch);
+    }
+
+    /**
+     * Restore the search gadget to its normal position.
+     * 
+     * @param animate Whether to animate the movement of the gadget.
+     */
+    public void stopSearch(boolean animate) {
+        setQuery("");
+        
+        // Set the search field back to focusable after making it unfocusable in
+        // startSearch, so that the home screen doesn't try to shift around when the
+        // keyboard comes up.
+        mSearchText.setFocusable(true);
+        // Only restore if we are not already restored.
+        if (getAnimation() == mMorphAnimation) {
+            if (animate && !isAtTop()) {
+                mUnmorphAnimation.setDuration(getAnimationDuration());
+                startAnimation(mUnmorphAnimation);
+            } else {
+                clearAnimation();
+            }
         }
-        Bundle appData = new Bundle();
-        appData.putString(SearchManager.SOURCE, "launcher-widget");
-        sendLaunchIntent(Intent.ACTION_SEARCH, null, query, appData, 0, null, mSearchable);
-        clearQuery();
+    }
+
+    private boolean isAtTop() {
+        return getTop() == 0;
+    }
+
+    private int getAnimationDuration() {
+        return (int) (getTop() / ANIMATION_VELOCITY);
+    }
+
+    /**
+     * Modify clearAnimation() to invalidate the parent. This works around
+     * an issue where the region where the end of the animation placed the view
+     * was not redrawn after clearing the animation.
+     */
+    @Override
+    public void clearAnimation() {
+        Animation animation = getAnimation();
+        if (animation != null) {
+            super.clearAnimation();
+            if (animation.hasEnded() 
+                    && animation.getFillAfter()
+                    && animation.willChangeBounds()) {
+                ((View) getParent()).invalidate();
+            } else {
+                invalidate();
+            }
+        }
     }
     
-    /**
-     * Assemble a search intent and send it.
-     * 
-     * This is copied from SearchDialog.
-     *
-     * @param action The intent to send, typically Intent.ACTION_SEARCH
-     * @param data The data for the intent
-     * @param query The user text entered (so far)
-     * @param appData The app data bundle (if supplied)
-     * @param actionKey If the intent was triggered by an action key, e.g. KEYCODE_CALL, it will
-     * be sent here.  Pass KeyEvent.KEYCODE_UNKNOWN for no actionKey code.
-     * @param actionMsg If the intent was triggered by an action key, e.g. KEYCODE_CALL, the
-     * corresponding tag message will be sent here.  Pass null for no actionKey message.
-     * @param si Reference to the current SearchableInfo.  Passed here so it can be used even after
-     * we've called dismiss(), which attempts to null mSearchable.
-     */
-    private void sendLaunchIntent(final String action, final Uri data, final String query,
-            final Bundle appData, int actionKey, final String actionMsg, final SearchableInfo si) {
-        Intent launcher = new Intent(action);
-        launcher.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        if (query != null) {
-            launcher.putExtra(SearchManager.QUERY, query);
-        }
-
-        if (data != null) {
-            launcher.setData(data);
-        }
-
-        if (appData != null) {
-            launcher.putExtra(SearchManager.APP_DATA, appData);
-        }
-
-        // add launch info (action key, etc.)
-        if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
-            launcher.putExtra(SearchManager.ACTION_KEY, actionKey);
-            launcher.putExtra(SearchManager.ACTION_MSG, actionMsg);
-        }
-
-        // attempt to enforce security requirement (no 3rd-party intents)
-        if (si != null) {
-            launcher.setComponent(si.mSearchActivity);
-        }
-
-        getContext().startActivity(launcher);
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        if (!hasWindowFocus && hasFocus()) {
-            mRestoreFocus = true;
-        }
-
-        super.onWindowFocusChanged(hasWindowFocus);
-
-        if (hasWindowFocus && mRestoreFocus) {
-            if (isInTouchMode()) {
-                final AutoCompleteTextView searchText = mSearchText;
-                searchText.setSelectAllOnFocus(false);
-                searchText.requestFocusFromTouch();
-                searchText.setSelectAllOnFocus(true);
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        if (!event.isSystem() && 
+                (keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
+                (keyCode != KeyEvent.KEYCODE_DPAD_DOWN) &&
+                (keyCode != KeyEvent.KEYCODE_DPAD_LEFT) &&
+                (keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) &&
+                (keyCode != KeyEvent.KEYCODE_DPAD_CENTER)) {
+            // Forward key events to Launcher, which will forward text 
+            // to search dialog
+            switch (event.getAction()) {
+                case KeyEvent.ACTION_DOWN:
+                    return mLauncher.onKeyDown(keyCode, event);
+                case KeyEvent.ACTION_MULTIPLE:
+                    return mLauncher.onKeyMultiple(keyCode, event.getRepeatCount(), event);
+                case KeyEvent.ACTION_UP:
+                    return mLauncher.onKeyUp(keyCode, event);
             }
-            mRestoreFocus = false;
         }
-    }
-
-    /**
-     * Implements TextWatcher (for EditText)
-     */
-    public void beforeTextChanged(CharSequence s, int start, int before, int after) { 
-    }
-
-    /**
-     * Implements TextWatcher (for EditText)
-     */
-    public void onTextChanged(CharSequence s, int start, int before, int after) {
-        // enable the button if we have one or more non-space characters
-        boolean enabled = TextUtils.getTrimmedLength(mSearchText.getText()) != 0;
-        mGoButton.setEnabled(enabled);
-        mGoButton.setFocusable(enabled);
-    }
-
-    /**
-     * Implements TextWatcher (for EditText)
-     */
-    public void afterTextChanged(Editable s) {
-    }
-
-    /**
-     * Implements OnKeyListener (for EditText and for button)
-     * 
-     * This plays some games with state in order to "soften" the strength of suggestions
-     * presented.  Suggestions should not be used unless the user specifically navigates to them
-     * (or clicks them, in which case it's obvious).  This is not the way that AutoCompleteTextBox
-     * normally works.
-     */
-    public final boolean onKey(View v, int keyCode, KeyEvent event) {
-        if (v == mSearchText) {
-            boolean searchTrigger = (keyCode == KeyEvent.KEYCODE_ENTER || 
-                    keyCode == KeyEvent.KEYCODE_SEARCH ||
-                    keyCode == KeyEvent.KEYCODE_DPAD_CENTER);
-            if (event.getAction() == KeyEvent.ACTION_UP) {
-//              Log.d(TAG, "onKey() ACTION_UP isPopupShowing:" + mSearchText.isPopupShowing());
-                if (!mSearchText.isPopupShowing()) {
-                    if (searchTrigger) {
-                        query();
-                        return true;
-                    }
-                }
-            } else {
-//              Log.d(TAG, "onKey() ACTION_DOWN isPopupShowing:" + mSearchText.isPopupShowing() +
-//                      " mItemSelected="+ mItemSelected);
-                if (searchTrigger && mItemSelected < 0) {
-                    query();
-                    return true;
-                }
-            }
-        } else if (v == mGoButton || v == mVoiceButton) {
-            boolean handled = false;
-            if (!event.isSystem() && 
-                    (keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
-                    (keyCode != KeyEvent.KEYCODE_DPAD_DOWN) &&
-                    (keyCode != KeyEvent.KEYCODE_DPAD_LEFT) &&
-                    (keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) &&
-                    (keyCode != KeyEvent.KEYCODE_DPAD_CENTER)) {
-                if (mSearchText.requestFocus()) {
-                    handled = mSearchText.dispatchKeyEvent(event);
-                }
-            }
-            return handled;
-        }
-
         return false;
     }
-    
-    @Override
-    public void setOnLongClickListener(OnLongClickListener l) {
-        super.setOnLongClickListener(l);
-        mLongClickListener = l;
-    }
-    
+
     /**
-     * Implements OnLongClickListener (for button)
+     * Implements OnLongClickListener to pass long clicks on child views 
+     * to the widget. This makes it possible to pick up the widget by long
+     * clicking on the text field or a button.
      */
     public boolean onLongClick(View v) {
-        // Pretend that a long press on a child view is a long press on the search widget
-        if (mLongClickListener != null) {
-            return mLongClickListener.onLongClick(this);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // Request focus unless the user tapped on the voice search button
-        final int x = (int) ev.getX();
-        final int y = (int) ev.getY();
-        final Rect frame = mTempRect;
-        mVoiceButton.getHitRect(frame);
-        if (!frame.contains(x, y)) {
-            requestFocusFromTouch();
-        }
-        return super.onInterceptTouchEvent(ev);
-    }
-    
-    /**
-     * In order to keep things simple, the external trigger will clear the query just before
-     * focusing, so as to give you a fresh query.  This way we eliminate any sources of
-     * accidental query launching.
-     */
-    public void clearQuery() {
-        mSearchText.setText(null);
+        return performLongClick();
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mSearchText = (AutoCompleteTextView) findViewById(R.id.input);
-        // TODO: This can be confusing when the user taps the text field to give the focus
-        // (it is not necessary but I ran into this issue several times myself)
-        // mTitleInput.setOnClickListener(this);
-        mSearchText.setOnKeyListener(this);
-        mSearchText.addTextChangedListener(this);
-
-        mGoButton = (ImageButton) findViewById(R.id.search_go_btn);
+        mSearchText = (TextView) findViewById(R.id.search_src_text);
         mVoiceButton = (ImageButton) findViewById(R.id.search_voice_btn);
-        mGoButton.setOnClickListener(this);
+
+        mSearchText.setOnKeyListener(this);
+
+        mSearchText.setOnClickListener(this);
         mVoiceButton.setOnClickListener(this);
-        mGoButton.setOnKeyListener(this);
-        mVoiceButton.setOnKeyListener(this);
-        
+        setOnClickListener(this);        
+
         mSearchText.setOnLongClickListener(this);
-        mGoButton.setOnLongClickListener(this);
         mVoiceButton.setOnLongClickListener(this);
-        
-        // disable the button since we start out w/empty input
-        mGoButton.setEnabled(false);
-        mGoButton.setFocusable(false);
-        
-        configureSearchableInfo();
-        configureSuggestions();
+
         configureVoiceSearchButton();
     }
-    
-    /**
-     * Cache of popup padding value after read from {@link Resources}.
-     */
-    private static float mPaddingInset = -1;
-    
-    /**
-     * When our size is changed, pass down adjusted width and offset values to
-     * correctly center the {@link AutoCompleteTextView} popup and include our
-     * padding.
-     */
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (changed) {
-            if (mPaddingInset == -1) {
-                mPaddingInset = getResources().getDimension(R.dimen.search_widget_inset);
-            }
-            
-            // Fill entire width of widget, minus padding inset
-            float paddedWidth = getWidth() - (mPaddingInset * 2);
-            float paddedOffset = -(mSearchText.getLeft() - mPaddingInset);
-                
-            mSearchText.setDropDownWidth((int) paddedWidth);
-            mSearchText.setDropDownHorizontalOffset((int) paddedOffset);
-        }
-    }
-    
-    /**
-     * Read the searchable info from the search manager
-     */
-    private void configureSearchableInfo() {
-        ISearchManager sms;
-        SearchableInfo searchable;
-        sms = ISearchManager.Stub.asInterface(ServiceManager.getService(Context.SEARCH_SERVICE));
-        try {
-            // TODO null isn't the published use of this API, but it works when global=true
-            // TODO better implementation:  defer all of this, let Home set it up 
-            searchable = sms.getSearchableInfo(null, true);
-        } catch (RemoteException e) {
-            searchable = null;
-        }
-        if (searchable == null) {
-            // no suggestions so just get out (no need to continue)
-            return;
-        }
-        mSearchable = searchable;
-    }
-    
+
     /**
      * If appropriate & available, configure voice search
      * 
@@ -384,346 +314,45 @@
      * voice search.
      */
     private void configureVoiceSearchButton() {
-        boolean voiceSearchVisible = false;
-        if (mSearchable.getVoiceSearchEnabled() && mSearchable.getVoiceSearchLaunchWebSearch()) {
-            // Enable the voice search button if there is an activity that can handle it
-            PackageManager pm = getContext().getPackageManager();
-            ResolveInfo ri = pm.resolveActivity(mVoiceSearchIntent,
-                    PackageManager.MATCH_DEFAULT_ONLY);
-            voiceSearchVisible = ri != null;
-        }
-        
+        // Enable the voice search button if there is an activity that can handle it
+        PackageManager pm = getContext().getPackageManager();
+        ResolveInfo ri = pm.resolveActivity(mVoiceSearchIntent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        boolean voiceSearchVisible = ri != null;
+
         // finally, set visible state of voice search button, as appropriate
         mVoiceButton.setVisibility(voiceSearchVisible ? View.VISIBLE : View.GONE);
     }
-     
-    /** The rest of the class deals with providing search suggestions */
-    
+
     /**
-     * Set up the suggestions provider mechanism
+     * Sets the {@link Launcher} that this gadget will call on to display the search dialog. 
      */
-    private void configureSuggestions() {
-        // get SearchableInfo
-        
-        mSearchText.setOnItemClickListener(this);
-        mSearchText.setOnItemSelectedListener(this);
-        
-        // attach the suggestions adapter
-        mSuggestionsAdapter = new SuggestionsAdapter(mContext, 
-                com.android.internal.R.layout.search_dropdown_item_2line, null,
-                SuggestionsAdapter.TWO_LINE_FROM, SuggestionsAdapter.TWO_LINE_TO, mSearchable);
-        mSearchText.setAdapter(mSuggestionsAdapter);
+    public void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
     }
-    
-    /**
-     * Remove internal cursor references when detaching from window which
-     * prevents {@link Context} leaks.
-     */
-    @Override
-    public void onDetachedFromWindow() {
-        if (mSuggestionsAdapter != null) {
-            mSuggestionsAdapter.changeCursor(null);
-            mSuggestionsAdapter = null;
-        }
-    }
-    
-    /**
-     * Implements OnItemClickListener
-     */
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-//      Log.d(TAG, "onItemClick() position " + position);
-        launchSuggestion(mSuggestionsAdapter, position);
-    }
-    
+
     /** 
-     * Implements OnItemSelectedListener
+     * Moves the view to the top left corner of its parent.
      */
-     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-//       Log.d(TAG, "onItemSelected() position " + position);
-         mItemSelected = position;
-     }
-
-     /** 
-      * Implements OnItemSelectedListener
-      */
-     public void onNothingSelected(AdapterView<?> parent) {
-//       Log.d(TAG, "onNothingSelected()");
-         mItemSelected = -1;
-     }
-
-    /**
-     * Code to launch a suggestion query.  
-     * 
-     * This is copied from SearchDialog.
-     * 
-     * @param ca The CursorAdapter containing the suggestions
-     * @param position The suggestion we'll be launching from
-     * 
-     * @return Returns true if a successful launch, false if could not (e.g. bad position)
-     */
-    private boolean launchSuggestion(CursorAdapter ca, int position) {
-        if (ca != null) {
-            Cursor c = ca.getCursor();
-            if ((c != null) && c.moveToPosition(position)) {
-                setupSuggestionIntent(c, mSearchable);
-                
-                SearchableInfo si = mSearchable;
-                String suggestionAction = mSuggestionAction;
-                Uri suggestionData = mSuggestionData;
-                String suggestionQuery = mSuggestionQuery;
-                sendLaunchIntent(suggestionAction, suggestionData, suggestionQuery, null,
-                                    KeyEvent.KEYCODE_UNKNOWN, null, si);
-                clearQuery();
-                return true;
-            }
-        }
-        return false;
-    }
-    
-    /**
-     * When a particular suggestion has been selected, perform the various lookups required
-     * to use the suggestion.  This includes checking the cursor for suggestion-specific data,
-     * and/or falling back to the XML for defaults;  It also creates REST style Uri data when
-     * the suggestion includes a data id.
-     * 
-     * NOTE:  Return values are in member variables mSuggestionAction, mSuggestionData and
-     * mSuggestionQuery.
-     * 
-     * This is copied from SearchDialog.
-     * 
-     * @param c The suggestions cursor, moved to the row of the user's selection
-     * @param si The searchable activity's info record
-     */
-    void setupSuggestionIntent(Cursor c, SearchableInfo si) {
-        try {
-            // use specific action if supplied, or default action if supplied, or fixed default
-            mSuggestionAction = null;
-            int column = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_ACTION);
-            if (column >= 0) {
-                final String action = c.getString(column);
-                if (action != null) {
-                    mSuggestionAction = action;
-                }
-            }
-            if (mSuggestionAction == null) {
-                mSuggestionAction = si.getSuggestIntentAction();
-            }
-            if (mSuggestionAction == null) {
-                mSuggestionAction = Intent.ACTION_SEARCH;
-            }
-            
-            // use specific data if supplied, or default data if supplied
-            String data = null;
-            column = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA);
-            if (column >= 0) {
-                final String rowData = c.getString(column);
-                if (rowData != null) {
-                    data = rowData;
-                }
-            }
-            if (data == null) {
-                data = si.getSuggestIntentData();
-            }
-            
-            // then, if an ID was provided, append it.
-            if (data != null) {
-                column = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
-                if (column >= 0) {
-                    final String id = c.getString(column);
-                    if (id != null) {
-                        data = data + "/" + Uri.encode(id);
-                    }
-                }
-            }
-            mSuggestionData = (data == null) ? null : Uri.parse(data);
-            
-            mSuggestionQuery = null;
-            column = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
-            if (column >= 0) {
-                final String query = c.getString(column);
-                if (query != null) {
-                    mSuggestionQuery = query;
-                }
-            }
-        } catch (RuntimeException e ) {
-            int rowNum;
-            try {                       // be really paranoid now
-                rowNum = c.getPosition();
-            } catch (RuntimeException e2 ) {
-                rowNum = -1;
-            }
-            Log.w(TAG, "Search Suggestions cursor at row " + rowNum + 
-                            " returned exception" + e.toString());
-        }
-    }
-
-    SearchAutoCompleteTextView getSearchInputField() {
-        return (SearchAutoCompleteTextView) mSearchText;
-    }
-
-    /**
-     * This class provides the filtering-based interface to suggestions providers.
-     * It is hardwired in a couple of places to support GoogleSearch - for example, it supports
-     * two-line suggestions, but it does not support icons.
-     */
-    private static class SuggestionsAdapter extends SimpleCursorAdapter {
-        public final static String[] TWO_LINE_FROM =    {SearchManager.SUGGEST_COLUMN_TEXT_1,
-                                                         SearchManager.SUGGEST_COLUMN_TEXT_2 };
-        public final static int[] TWO_LINE_TO =         {com.android.internal.R.id.text1, 
-                                                         com.android.internal.R.id.text2};
-        
-        private final String TAG = "SuggestionsAdapter";
-        
-        Filter mFilter;
-        SearchableInfo mSearchable;
-        private Resources mProviderResources;
-        String[] mFromStrings;
-
-        public SuggestionsAdapter(Context context, int layout, Cursor c,
-                String[] from, int[] to, SearchableInfo searchable) {
-            super(context, layout, c, from, to);
-            mFromStrings = from;
-            mSearchable = searchable;
-            
-            // set up provider resources (gives us icons, etc.)
-            Context activityContext = mSearchable.getActivityContext(mContext);
-            Context providerContext = mSearchable.getProviderContext(mContext, activityContext);
-            mProviderResources = providerContext.getResources();
-        }
-        
-        /**
-         * Use the search suggestions provider to obtain a live cursor.  This will be called
-         * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
-         * The results will be processed in the UI thread and changeCursor() will be called.
-         */
+    private class ToParentOriginAnimation extends Animation {
         @Override
-        public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
-            String query = (constraint == null) ? "" : constraint.toString();
-            return getSuggestions(mSearchable, query);
+        protected void applyTransformation(float interpolatedTime, Transformation t) {
+            float dx = -getLeft() * interpolatedTime;
+            float dy = -getTop() * interpolatedTime;
+            t.getMatrix().setTranslate(dx, dy);
         }
-        
-        /**
-         * Overriding this allows us to write the selected query back into the box.
-         * NOTE:  This is a vastly simplified version of SearchDialog.jamQuery() and does
-         * not universally support the search API.  But it is sufficient for Google Search.
-         */
-        @Override
-        public CharSequence convertToString(Cursor cursor) {
-            CharSequence result = null;
-            if (cursor != null) {
-                int column = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
-                if (column >= 0) {
-                    final String query = cursor.getString(column);
-                    if (query != null) {
-                        result = query;
-                    }
-                }
-            }
-            return result;
-        }
-
-        /**
-         * Get the query cursor for the search suggestions.
-         * 
-         * TODO this is functionally identical to the version in SearchDialog.java.  Perhaps it 
-         * could be hoisted into SearchableInfo or some other shared spot.
-         * 
-         * @param query The search text entered (so far)
-         * @return Returns a cursor with suggestions, or null if no suggestions 
-         */
-        private Cursor getSuggestions(final SearchableInfo searchable, final String query) {
-            Cursor cursor = null;
-            if (searchable.getSuggestAuthority() != null) {
-                try {
-                    StringBuilder uriStr = new StringBuilder("content://");
-                    uriStr.append(searchable.getSuggestAuthority());
-
-                    // if content path provided, insert it now
-                    final String contentPath = searchable.getSuggestPath();
-                    if (contentPath != null) {
-                        uriStr.append('/');
-                        uriStr.append(contentPath);
-                    }
-
-                    // append standard suggestion query path 
-                    uriStr.append('/' + SearchManager.SUGGEST_URI_PATH_QUERY);
-
-                    // inject query, either as selection args or inline
-                    String[] selArgs = null;
-                    if (searchable.getSuggestSelection() != null) {    // use selection if provided
-                        selArgs = new String[] {query};
-                    } else {
-                        uriStr.append('/');                             // no sel, use REST pattern
-                        uriStr.append(Uri.encode(query));
-                    }
-
-                    // finally, make the query
-                    cursor = mContext.getContentResolver().query(
-                                                        Uri.parse(uriStr.toString()), null, 
-                                                        searchable.getSuggestSelection(), selArgs,
-                                                        null);
-                } catch (RuntimeException e) {
-                    Log.w(TAG, "Search Suggestions query returned exception " + e.toString());
-                    cursor = null;
-                }
-            }
-            
-            return cursor;
-        }
-
-        /**
-         * Overriding this allows us to affect the way that an icon is loaded.  Specifically,
-         * we can be more controlling about the resource path (and allow icons to come from other
-         * packages).
-         * 
-         * TODO: This is 100% identical to the version in SearchDialog.java
-         *
-         * @param v ImageView to receive an image
-         * @param value the value retrieved from the cursor
-         */
-        @Override
-        public void setViewImage(ImageView v, String value) {
-            int resID;
-            Drawable img = null;
-
-            try {
-                resID = Integer.parseInt(value);
-                if (resID != 0) {
-                    img = mProviderResources.getDrawable(resID);
-                }
-            } catch (NumberFormatException nfe) {
-                // img = null;
-            } catch (NotFoundException e2) {
-                // img = null;
-            }
-            
-            // finally, set the image to whatever we've gotten
-            v.setImageDrawable(img);
-        }
-        
-        /**
-         * This method is overridden purely to provide a bit of protection against
-         * flaky content providers.
-         * 
-         * TODO: This is 100% identical to the version in SearchDialog.java
-         * 
-         * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
-         */
-        @Override 
-        public View getView(int position, View convertView, ViewGroup parent) {
-            try {
-                return super.getView(position, convertView, parent);
-            } catch (RuntimeException e) {
-                Log.w(TAG, "Search Suggestions cursor returned exception " + e.toString());
-                // what can I return here?
-                View v = newView(mContext, mCursor, parent);
-                if (v != null) {
-                    TextView tv = (TextView) v.findViewById(com.android.internal.R.id.text1);
-                    tv.setText(e.toString());
-                }
-                return v;
-            }
-        }
-
     }
+
+    /** 
+     * Moves the view from the top left corner of its parent.
+     */
+    private class FromParentOriginAnimation extends Animation {
+        @Override
+        protected void applyTransformation(float interpolatedTime, Transformation t) {
+            float dx = -getLeft() * (1.0f - interpolatedTime);
+            float dy = -getTop() * (1.0f - interpolatedTime);
+            t.getMatrix().setTranslate(dx, dy);
+        }
+    }
+
 }
diff --git a/src/com/android/launcher/Workspace.java b/src/com/android/launcher/Workspace.java
index 359767a..c76fb7e 100644
--- a/src/com/android/launcher/Workspace.java
+++ b/src/com/android/launcher/Workspace.java
@@ -1027,7 +1027,7 @@
         }
         return result;
     }
-    
+
     /**
      * Find a search widget on the given screen
      */
@@ -1041,102 +1041,14 @@
         }
         return null;
     }
-    
+
     /**
-     * Focuses on the search widget on the specified screen,
-     * if there is one.  Also clears the current search selection so we don't 
+     * Gets the first search widget on the current screen, if there is one.
+     * Returns <code>null</code> otherwise.
      */
-    private boolean focusOnSearch(int screen) {
-        CellLayout currentScreen = (CellLayout) getChildAt(screen);
-        final Search searchWidget = findSearchWidget(currentScreen);
-        if (searchWidget != null) {
-            // This is necessary when focus on search is requested from the menu
-            // If the workspace was not in touch mode before the menu is invoked
-            // and the user clicks "Search" by touching the menu item, the following
-            // happens:
-            //
-            // - We request focus from touch on the search widget
-            // - The search widget gains focus
-            // - The window focus comes back to Home's window
-            // - The touch mode change is propagated to Home's window
-            // - The search widget is not focusable in touch mode and ViewRoot
-            //   clears its focus
-            //
-            // Forcing focusable in touch mode ensures the search widget will
-            // keep the focus no matter what happens.
-            //
-            // Note: the search input field disables focusable in touch mode
-            // after the window gets the focus back, see SearchAutoCompleteTextView
-            final SearchAutoCompleteTextView input = searchWidget.getSearchInputField();
-            input.setFocusableInTouchMode(true);
-            input.showKeyboardOnNextFocus();
-
-            if (isInTouchMode()) {
-                searchWidget.requestFocusFromTouch();
-            } else {
-                searchWidget.requestFocus();
-            }
-            searchWidget.clearQuery();
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     * Snap to the nearest screen with a search widget and give it focus
-     * 
-     * @return True if a search widget was found
-     */
-    public boolean snapToSearch() {
-        // The screen we are searching
-        int current = mCurrentScreen;
-        
-        // first position scanned so far
-        int first = current;
-
-        // last position scanned so far
-        int last = current;
-
-        // True if we should move down on the next iteration
-        boolean next = false;
-
-        // True when we have looked at the first item in the data
-        boolean hitFirst;
-
-        // True when we have looked at the last item in the data
-        boolean hitLast;
-        
-        final int count = getChildCount();
-
-        while (true) {
-            if (focusOnSearch(current)) {
-                return true;
-            }
-
-            hitLast = last == count - 1;
-            hitFirst = first == 0;
-
-            if (hitLast && hitFirst) {
-                // Looked at everything
-                break;
-            }
-
-            if (hitFirst || (next && !hitLast)) {
-                // Either we hit the top, or we are trying to move down
-                last++;
-                current = last;
-                // Try going up next time
-                next = false;
-            } else {
-                // Either we hit the bottom, or we are trying to move up
-                first--;
-                current = first;
-                // Try going down next time
-                next = true;
-            }
-
-        }
-        return false;
+    public Search findSearchWidgetOnCurrentScreen() {
+        CellLayout currentScreen = (CellLayout)getChildAt(mCurrentScreen);
+        return findSearchWidget(currentScreen);
     }
 
     public Folder getFolderForTag(Object tag) {
