diff --git a/src/com/android/launcher/AddAdapter.java b/src/com/android/launcher/AddAdapter.java
new file mode 100644
index 0000000..18b36d5
--- /dev/null
+++ b/src/com/android/launcher/AddAdapter.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Adapter showing the types of items that can be added to a {@link Workspace}.
+ */
+public class AddAdapter extends BaseAdapter {
+    
+    private final Launcher mLauncher;
+    private final LayoutInflater mInflater;
+    
+    private final ArrayList<ListItem> mItems = new ArrayList<ListItem>();
+    
+    public static final int ITEM_APPLICATION = 0;
+    public static final int ITEM_SHORTCUT = 1;
+    public static final int ITEM_SEARCH = 2;
+    public static final int ITEM_GADGET = 3;
+    public static final int ITEM_LIVE_FOLDER = 4;
+    public static final int ITEM_FOLDER = 5;
+    public static final int ITEM_WALLPAPER = 6;
+    
+    /**
+     * Specific item in our list.
+     */
+    public class ListItem {
+        public final CharSequence text;
+        public final Drawable image;
+        public final int actionTag;
+        
+        public ListItem(Resources res, int textResourceId, int imageResourceId, int actionTag) {
+            text = res.getString(textResourceId);
+            if (imageResourceId != -1) {
+                image = res.getDrawable(imageResourceId);
+            } else {
+                image = null;
+            }
+            this.actionTag = actionTag;
+        }
+    }
+    
+    public AddAdapter(Launcher launcher) {
+        super();
+        
+        mLauncher = launcher;
+        mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        
+        // Create default actions
+        Resources res = launcher.getResources();
+        
+        mItems.add(new ListItem(res, R.string.group_applications,
+                R.drawable.ic_launcher_application, ITEM_APPLICATION));
+        
+        mItems.add(new ListItem(res, R.string.group_shortcuts,
+                R.drawable.ic_launcher_empty, ITEM_SHORTCUT));
+        
+        mItems.add(new ListItem(res, R.string.group_search,
+                R.drawable.ic_search_gadget, ITEM_SEARCH));
+        
+        mItems.add(new ListItem(res, R.string.group_widgets,
+                R.drawable.ic_launcher_gadget, ITEM_GADGET));
+        
+        mItems.add(new ListItem(res, R.string.group_live_folders,
+                R.drawable.ic_launcher_empty, ITEM_LIVE_FOLDER));
+        
+        mItems.add(new ListItem(res, R.string.group_folder,
+                R.drawable.ic_launcher_folder, ITEM_FOLDER));
+        
+        mItems.add(new ListItem(res, R.string.group_wallpapers,
+                R.drawable.ic_launcher_gallery, ITEM_WALLPAPER));
+
+    }
+
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ListItem item = (ListItem) getItem(position);
+        
+        if (convertView == null) {
+            convertView = mInflater.inflate(R.layout.add_list_item, parent, false);
+        }
+        
+        TextView textView = (TextView) convertView;
+        textView.setTag(item);
+        textView.setText(item.text);
+        textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null);
+        
+        return convertView;
+    }
+
+    public int getCount() {
+        return mItems.size();
+    }
+
+    public Object getItem(int position) {
+        return mItems.get(position);
+    }
+
+    public long getItemId(int position) {
+        return position;
+    }
+    
+}
diff --git a/src/com/android/launcher/AllAppsGridView.java b/src/com/android/launcher/AllAppsGridView.java
new file mode 100644
index 0000000..b8f7902
--- /dev/null
+++ b/src/com/android/launcher/AllAppsGridView.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.GridView;
+import android.widget.AdapterView;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
+import android.graphics.Canvas;
+
+public class AllAppsGridView extends GridView implements AdapterView.OnItemClickListener,
+        AdapterView.OnItemLongClickListener, DragSource {
+
+    private DragController mDragger;
+    private Launcher mLauncher;
+    private Bitmap mTexture;
+    private Paint mPaint;
+    private int mTextureWidth;
+    private int mTextureHeight;
+
+    public AllAppsGridView(Context context) {
+        super(context);
+    }
+
+    public AllAppsGridView(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.gridViewStyle);
+    }
+
+    public AllAppsGridView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AllAppsGridView, defStyle, 0);
+        final int textureId = a.getResourceId(R.styleable.AllAppsGridView_texture, 0);
+        if (textureId != 0) {
+            mTexture = BitmapFactory.decodeResource(getResources(), textureId);
+            mTextureWidth = mTexture.getWidth();
+            mTextureHeight = mTexture.getHeight();
+
+            mPaint = new Paint();
+            mPaint.setDither(false);
+        }
+        a.recycle();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        setOnItemClickListener(this);
+        setOnItemLongClickListener(this);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        final Bitmap texture = mTexture;
+        final Paint paint = mPaint;
+
+        final int width = getWidth();
+        final int height = getHeight();
+
+        final int textureWidth = mTextureWidth;
+        final int textureHeight = mTextureHeight;
+
+        int x = 0;
+        int y;
+
+        while (x < width) {
+            y = 0;
+            while (y < height) {
+                canvas.drawBitmap(texture, x, y, paint);
+                y += textureHeight;
+            }
+            x += textureWidth;
+        }
+
+        super.draw(canvas);
+    }
+
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
+        mLauncher.startActivitySafely(app.intent);
+    }
+
+    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+        if (!view.isInTouchMode()) {
+            return false;
+        }
+
+        ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
+        app = new ApplicationInfo(app);
+
+        mDragger.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
+        mLauncher.closeAllApplications();
+
+        return true;
+    }
+
+    public void setDragger(DragController dragger) {
+        mDragger = dragger;
+    }
+
+    public void onDropCompleted(View target, boolean success) {
+    }
+
+    void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
+    }
+}
diff --git a/src/com/android/launcher/ApplicationInfo.java b/src/com/android/launcher/ApplicationInfo.java
new file mode 100644
index 0000000..9bc0950
--- /dev/null
+++ b/src/com/android/launcher/ApplicationInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Represents a launchable application. An application is made of a name (or title),
+ * an intent and an icon.
+ */
+class ApplicationInfo extends ItemInfo {
+
+    /**
+     * The application name.
+     */
+    CharSequence title;
+
+    /**
+     * The intent used to start the application.
+     */
+    Intent intent;
+
+    /**
+     * The application icon.
+     */
+    Drawable icon;
+
+    /**
+     * When set to true, indicates that the icon has been resized.
+     */
+    boolean filtered;
+
+    /**
+     * Indicates whether the icon comes from an application's resource (if false)
+     * or from a custom Bitmap (if true.)
+     */
+    boolean customIcon;
+
+    /**
+     * If isShortcut=true and customIcon=false, this contains a reference to the
+     * shortcut icon as an application's resource.
+     */
+    Intent.ShortcutIconResource iconResource;
+
+    ApplicationInfo() {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+    }
+    
+    public ApplicationInfo(ApplicationInfo info) {
+        super(info);
+        title = info.title.toString();
+        intent = new Intent(info.intent);
+        if (info.iconResource != null) {
+            iconResource = new Intent.ShortcutIconResource();
+            iconResource.packageName = info.iconResource.packageName;
+            iconResource.resourceName = info.iconResource.resourceName;
+        }
+        icon = info.icon;
+        filtered = info.filtered;
+        customIcon = info.customIcon;
+    }
+
+    /**
+     * Creates the application intent based on a component name and various launch flags.
+     * Sets {@link #itemType} to {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION}.
+     *
+     * @param className the class name of the component representing the intent
+     * @param launchFlags the launch flags
+     */
+    final void setActivity(ComponentName className, int launchFlags) {
+        intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.setComponent(className);
+        intent.setFlags(launchFlags);
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+    }
+
+    @Override
+    void onAddToDatabase(ContentValues values) {
+        super.onAddToDatabase(values);
+
+        String titleStr = title != null ? title.toString() : null;
+        values.put(LauncherSettings.Favorites.TITLE, titleStr);
+
+        String uri = intent != null ? intent.toURI() : null;
+        values.put(LauncherSettings.Favorites.INTENT, uri);
+
+        if (customIcon) {
+            values.put(LauncherSettings.Favorites.ICON_TYPE,
+                    LauncherSettings.Favorites.ICON_TYPE_BITMAP);
+            Bitmap bitmap = ((FastBitmapDrawable) icon).getBitmap();
+            writeBitmap(values, bitmap);
+        } else {
+            values.put(LauncherSettings.Favorites.ICON_TYPE,
+                    LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
+            if (iconResource != null) {
+                values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
+                values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return title.toString();
+    }
+}
diff --git a/src/com/android/launcher/ApplicationsAdapter.java b/src/com/android/launcher/ApplicationsAdapter.java
new file mode 100644
index 0000000..97891b2
--- /dev/null
+++ b/src/com/android/launcher/ApplicationsAdapter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * GridView adapter to show the list of applications and shortcuts
+ */
+public class ApplicationsAdapter extends ArrayAdapter<ApplicationInfo> {
+    private final LayoutInflater mInflater;
+
+    public ApplicationsAdapter(Context context, ArrayList<ApplicationInfo> apps) {
+        super(context, 0, apps);
+        mInflater = LayoutInflater.from(context);
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        final ApplicationInfo info = getItem(position);
+
+        if (convertView == null) {
+            convertView = mInflater.inflate(R.layout.application_boxed, parent, false);
+        }
+
+        if (!info.filtered) {
+            info.icon = Utilities.createIconThumbnail(info.icon, getContext());
+            info.filtered = true;
+        }
+
+        final TextView textView = (TextView) convertView;
+        textView.setCompoundDrawablesWithIntrinsicBounds(null, info.icon, null, null);
+        textView.setText(info.title);
+
+        return convertView;
+    }
+}
diff --git a/src/com/android/launcher/BubbleTextView.java b/src/com/android/launcher/BubbleTextView.java
new file mode 100644
index 0000000..3782454
--- /dev/null
+++ b/src/com/android/launcher/BubbleTextView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.TextView;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.text.Layout;
+
+/**
+ * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
+ * because we want to make the bubble taller than the text and TextView's clip is
+ * too aggressive.
+ */
+public class BubbleTextView extends TextView {
+    private static final float CORNER_RADIUS = 8.0f;
+    private static final float PADDING_H = 5.0f;
+    private static final float PADDING_V = 1.0f;
+
+    private final RectF mRect = new RectF();
+    private Paint mPaint;
+
+    private boolean mBackgroundSizeChanged;
+    private Drawable mBackground;
+    private float mCornerRadius;
+    private float mPaddingH;
+    private float mPaddingV;
+
+    public BubbleTextView(Context context) {
+        super(context);
+        init();
+    }
+
+    public BubbleTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    private void init() {
+        setFocusable(true);
+        mBackground = getBackground();
+        setBackgroundDrawable(null);
+        mBackground.setCallback(this);
+
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background));
+
+        final float scale = getContext().getResources().getDisplayMetrics().density;
+        mCornerRadius = CORNER_RADIUS * scale;
+        mPaddingH = PADDING_H * scale;
+        //noinspection PointlessArithmeticExpression
+        mPaddingV = PADDING_V * scale;
+    }
+
+    @Override
+    protected boolean setFrame(int left, int top, int right, int bottom) {
+        if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
+            mBackgroundSizeChanged = true;
+        }
+        return super.setFrame(left, top, right, bottom);
+    }
+
+    @Override
+    protected boolean verifyDrawable(Drawable who) {
+        return who == mBackground || super.verifyDrawable(who);
+    }
+
+    @Override
+    protected void drawableStateChanged() {
+        Drawable d = mBackground;
+        if (d != null && d.isStateful()) {
+            d.setState(getDrawableState());
+        }
+        super.drawableStateChanged();
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        final Drawable background = mBackground;
+        if (background != null) {
+            final int scrollX = mScrollX;
+            final int scrollY = mScrollY;
+
+            if (mBackgroundSizeChanged) {
+                background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
+                mBackgroundSizeChanged = false;
+            }
+
+            if ((scrollX | scrollY) == 0) {
+                background.draw(canvas);
+            } else {
+                canvas.translate(scrollX, scrollY);
+                background.draw(canvas);
+                canvas.translate(-scrollX, -scrollY);
+            }
+        }
+
+        final Layout layout = getLayout();
+        final RectF rect = mRect;
+        final int left = getCompoundPaddingLeft();
+        final int top = getExtendedPaddingTop();
+
+        rect.set(left + layout.getLineLeft(0) - mPaddingH,
+                top + layout.getLineTop(0) -  mPaddingV,
+                Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft),
+                top + layout.getLineBottom(0) + mPaddingV);
+        canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mPaint);
+
+        super.draw(canvas);
+    }
+}
diff --git a/src/com/android/launcher/CellLayout.java b/src/com/android/launcher/CellLayout.java
new file mode 100644
index 0000000..ff8bff4
--- /dev/null
+++ b/src/com/android/launcher/CellLayout.java
@@ -0,0 +1,1010 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.ContextMenu;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+public class CellLayout extends ViewGroup {
+    private boolean mPortrait;
+
+    private int mCellWidth;
+    private int mCellHeight;
+    
+    private int mLongAxisStartPadding;
+    private int mLongAxisEndPadding;
+
+    private int mShortAxisStartPadding;
+    private int mShortAxisEndPadding;
+
+    private int mShortAxisCells;
+    private int mLongAxisCells;
+
+    private int mWidthGap;
+    private int mHeightGap;
+
+    private final Rect mRect = new Rect();
+    private final CellInfo mCellInfo = new CellInfo();
+    
+    int[] mCellXY = new int[2];
+    
+    boolean[][] mOccupied;
+
+    private RectF mDragRect = new RectF();
+
+    private boolean mDirtyTag;
+
+    public CellLayout(Context context) {
+        this(context, null);
+    }
+
+    public CellLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CellLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
+
+        mCellWidth = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10);
+        mCellHeight = a.getDimensionPixelSize(R.styleable.CellLayout_cellHeight, 10);
+        
+        mLongAxisStartPadding = 
+            a.getDimensionPixelSize(R.styleable.CellLayout_longAxisStartPadding, 10);
+        mLongAxisEndPadding = 
+            a.getDimensionPixelSize(R.styleable.CellLayout_longAxisEndPadding, 10);
+        mShortAxisStartPadding =
+            a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisStartPadding, 10);
+        mShortAxisEndPadding = 
+            a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisEndPadding, 10);
+        
+        mShortAxisCells = a.getInt(R.styleable.CellLayout_shortAxisCells, 4);
+        mLongAxisCells = a.getInt(R.styleable.CellLayout_longAxisCells, 4);
+
+        a.recycle();
+
+        setAlwaysDrawnWithCacheEnabled(false);
+
+        if (mOccupied == null) {
+            if (mPortrait) {
+                mOccupied = new boolean[mShortAxisCells][mLongAxisCells];
+            } else {
+                mOccupied = new boolean[mLongAxisCells][mShortAxisCells];
+            }
+        }
+    }
+
+    int getCountX() {
+        return mPortrait ? mShortAxisCells : mLongAxisCells;
+    }
+
+    int getCountY() {
+        return mPortrait ? mLongAxisCells : mShortAxisCells;
+    }
+
+    @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        // Generate an id for each view, this assumes we have at most 256x256 cells
+        // per workspace screen
+        final LayoutParams cellParams = (LayoutParams) params;
+        child.setId(((getId() & 0xFF) << 16) |
+                (cellParams.cellX & 0xFF) << 8 | (cellParams.cellY & 0xFF));
+
+        super.addView(child, index, params);
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        super.requestChildFocus(child, focused);
+        if (child != null) {
+            Rect r = new Rect();
+            child.getDrawingRect(r);
+            requestRectangleOnScreen(r);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mCellInfo.screen = ((ViewGroup) getParent()).indexOfChild(this);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        final int action = ev.getAction();
+        final CellInfo cellInfo = mCellInfo;
+
+        if (action == MotionEvent.ACTION_DOWN) {
+            final Rect frame = mRect;
+            final int x = (int) ev.getX() + mScrollX;
+            final int y = (int) ev.getY() + mScrollY;
+            final int count = getChildCount();
+
+            boolean found = false;
+            for (int i = count - 1; i >= 0; i--) {
+                final View child = getChildAt(i);
+
+                if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) {
+                    child.getHitRect(frame);
+                    if (frame.contains(x, y)) {
+                        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                        cellInfo.cell = child;
+                        cellInfo.cellX = lp.cellX;
+                        cellInfo.cellY = lp.cellY;
+                        cellInfo.spanX = lp.cellHSpan;
+                        cellInfo.spanY = lp.cellVSpan;
+                        cellInfo.valid = true;
+                        found = true;
+                        mDirtyTag = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!found) {
+                int cellXY[] = mCellXY;
+                pointToCellExact(x, y, cellXY);
+
+                final boolean portrait = mPortrait;
+                final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
+                final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
+
+                final boolean[][] occupied = mOccupied;
+                findOccupiedCells(xCount, yCount, occupied);
+
+                cellInfo.cell = null;
+                cellInfo.cellX = cellXY[0];
+                cellInfo.cellY = cellXY[1];
+                cellInfo.spanX = 1;
+                cellInfo.spanY = 1;
+                cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
+                        cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
+
+                // Instead of finding the interesting vacant cells here, wait until a
+                // caller invokes getTag() to retrieve the result. Finding the vacant
+                // cells is a bit expensive and can generate many new objects, it's
+                // therefore better to defer it until we know we actually need it.
+
+                mDirtyTag = true;
+            }
+            setTag(cellInfo);
+        } else if (action == MotionEvent.ACTION_UP) {
+            cellInfo.cell = null;
+            cellInfo.cellX = -1;
+            cellInfo.cellY = -1;
+            cellInfo.spanX = 0;
+            cellInfo.spanY = 0;
+            cellInfo.valid = false;
+            mDirtyTag = false;
+            setTag(cellInfo);
+        }
+
+        return false;
+    }
+
+    @Override
+    public CellInfo getTag() {
+        final CellInfo info = (CellInfo) super.getTag();
+        if (mDirtyTag && info.valid) {
+            final boolean portrait = mPortrait;
+            final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
+            final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
+
+            final boolean[][] occupied = mOccupied;
+            findOccupiedCells(xCount, yCount, occupied);
+
+            findIntersectingVacantCells(info, info.cellX, info.cellY, xCount, yCount, occupied);
+
+            mDirtyTag = false;
+        }
+        return info;
+    }
+
+    private static void findIntersectingVacantCells(CellInfo cellInfo, int x, int y,
+            int xCount, int yCount, boolean[][] occupied) {
+
+        cellInfo.maxVacantSpanX = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanY = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE;
+        cellInfo.clearVacantCells();
+
+        if (occupied[x][y]) {
+            return;
+        }
+
+        cellInfo.current.set(x, y, x, y);
+
+        findVacantCell(cellInfo.current, xCount, yCount, occupied, cellInfo);
+    }
+
+    private static void findVacantCell(Rect current, int xCount, int yCount, boolean[][] occupied,
+            CellInfo cellInfo) {
+
+        addVacantCell(current, cellInfo);
+
+        if (current.left > 0) {
+            if (isColumnEmpty(current.left - 1, current.top, current.bottom, occupied)) {
+                current.left--;
+                findVacantCell(current, xCount, yCount, occupied, cellInfo);
+                current.left++;
+            }
+        }
+
+        if (current.right < xCount - 1) {
+            if (isColumnEmpty(current.right + 1, current.top, current.bottom, occupied)) {
+                current.right++;
+                findVacantCell(current, xCount, yCount, occupied, cellInfo);
+                current.right--;
+            }
+        }
+
+        if (current.top > 0) {
+            if (isRowEmpty(current.top - 1, current.left, current.right, occupied)) {
+                current.top--;
+                findVacantCell(current, xCount, yCount, occupied, cellInfo);
+                current.top++;
+            }
+        }
+
+        if (current.bottom < yCount - 1) {
+            if (isRowEmpty(current.bottom + 1, current.left, current.right, occupied)) {
+                current.bottom++;
+                findVacantCell(current, xCount, yCount, occupied, cellInfo);
+                current.bottom--;
+            }
+        }
+    }
+
+    private static void addVacantCell(Rect current, CellInfo cellInfo) {
+        CellInfo.VacantCell cell = CellInfo.VacantCell.acquire();
+        cell.cellX = current.left;
+        cell.cellY = current.top;
+        cell.spanX = current.right - current.left + 1;
+        cell.spanY = current.bottom - current.top + 1;
+        if (cell.spanX > cellInfo.maxVacantSpanX) {
+            cellInfo.maxVacantSpanX = cell.spanX;
+            cellInfo.maxVacantSpanXSpanY = cell.spanY;
+        }
+        if (cell.spanY > cellInfo.maxVacantSpanY) {
+            cellInfo.maxVacantSpanY = cell.spanY;
+            cellInfo.maxVacantSpanYSpanX = cell.spanX;
+        }
+        cellInfo.vacantCells.add(cell);
+    }
+
+    private static boolean isColumnEmpty(int x, int top, int bottom, boolean[][] occupied) {
+        for (int y = top; y <= bottom; y++) {
+            if (occupied[x][y]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean isRowEmpty(int y, int left, int right, boolean[][] occupied) {
+        for (int x = left; x <= right; x++) {
+            if (occupied[x][y]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    CellInfo findAllVacantCells(boolean[] occupiedCells) {
+        final boolean portrait = mPortrait;
+        final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
+        final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
+
+        boolean[][] occupied = mOccupied;
+
+        if (occupiedCells != null) {
+            for (int y = 0; y < yCount; y++) {
+                for (int x = 0; x < xCount; x++) {
+                    occupied[x][y] = occupiedCells[y * xCount + x];
+                }
+            }
+        } else {
+            findOccupiedCells(xCount, yCount, occupied);
+        }
+
+        CellInfo cellInfo = new CellInfo();
+
+        cellInfo.cellX = -1;
+        cellInfo.cellY = -1;
+        cellInfo.spanY = 0;
+        cellInfo.spanX = 0;
+        cellInfo.maxVacantSpanX = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanY = Integer.MIN_VALUE;
+        cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE;
+        cellInfo.screen = mCellInfo.screen;
+
+        Rect current = cellInfo.current;
+
+        for (int x = 0; x < xCount; x++) {
+            for (int y = 0; y < yCount; y++) {
+                if (!occupied[x][y]) {
+                    current.set(x, y, x, y);
+                    findVacantCell(current, xCount, yCount, occupied, cellInfo);
+                    occupied[x][y] = true;
+                }
+            }
+        }
+
+        cellInfo.valid = cellInfo.vacantCells.size() > 0;
+
+        // Assume the caller will perform their own cell searching, otherwise we
+        // risk causing an unnecessary rebuild after findCellForSpan()
+        
+        return cellInfo;
+    }
+
+    /**
+     * Given a point, return the cell that strictly encloses that point 
+     * @param x X coordinate of the point
+     * @param y Y coordinate of the point
+     * @param result Array of 2 ints to hold the x and y coordinate of the cell
+     */
+    void pointToCellExact(int x, int y, int[] result) {
+        final boolean portrait = mPortrait;
+        
+        final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
+        final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
+
+        result[0] = (x - hStartPadding) / (mCellWidth + mWidthGap);
+        result[1] = (y - vStartPadding) / (mCellHeight + mHeightGap);
+
+        final int xAxis = portrait ? mShortAxisCells : mLongAxisCells;
+        final int yAxis = portrait ? mLongAxisCells : mShortAxisCells;
+
+        if (result[0] < 0) result[0] = 0;
+        if (result[0] >= xAxis) result[0] = xAxis - 1;
+        if (result[1] < 0) result[1] = 0;
+        if (result[1] >= yAxis) result[1] = yAxis - 1;
+    }
+    
+    /**
+     * Given a point, return the cell that most closely encloses that point
+     * @param x X coordinate of the point
+     * @param y Y coordinate of the point
+     * @param result Array of 2 ints to hold the x and y coordinate of the cell
+     */
+    void pointToCellRounded(int x, int y, int[] result) {
+        pointToCellExact(x + (mCellWidth / 2), y + (mCellHeight / 2), result);
+    }
+
+    /**
+     * Given a cell coordinate, return the point that represents the upper left corner of that cell
+     * 
+     * @param cellX X coordinate of the cell 
+     * @param cellY Y coordinate of the cell
+     * 
+     * @param result Array of 2 ints to hold the x and y coordinate of the point
+     */
+    void cellToPoint(int cellX, int cellY, int[] result) {
+        final boolean portrait = mPortrait;
+        
+        final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
+        final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
+
+
+        result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap);
+        result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // TODO: currently ignoring padding
+        
+        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
+        int widthSpecSize =  MeasureSpec.getSize(widthMeasureSpec);
+        
+        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
+        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);
+        
+        if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
+            throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions");
+        }
+
+        final int shortAxisCells = mShortAxisCells;
+        final int longAxisCells = mLongAxisCells;
+        final int longAxisStartPadding = mLongAxisStartPadding;
+        final int longAxisEndPadding = mLongAxisEndPadding;
+        final int shortAxisStartPadding = mShortAxisStartPadding;
+        final int shortAxisEndPadding = mShortAxisEndPadding;
+        final int cellWidth = mCellWidth;
+        final int cellHeight = mCellHeight;
+
+        mPortrait = heightSpecSize > widthSpecSize;
+
+        int numShortGaps = shortAxisCells - 1;
+        int numLongGaps = longAxisCells - 1;
+
+        if (mPortrait) {
+            int vSpaceLeft = heightSpecSize - longAxisStartPadding - longAxisEndPadding
+                    - (cellHeight * longAxisCells);
+            mHeightGap = vSpaceLeft / numLongGaps;
+
+            int hSpaceLeft = widthSpecSize - shortAxisStartPadding - shortAxisEndPadding
+                    - (cellWidth * shortAxisCells);
+            if (numShortGaps > 0) {
+                mWidthGap = hSpaceLeft / numShortGaps;
+            } else {
+                mWidthGap = 0;
+            }
+        } else {
+            int hSpaceLeft = widthSpecSize - longAxisStartPadding - longAxisEndPadding
+                    - (cellWidth * longAxisCells);
+            mWidthGap = hSpaceLeft / numLongGaps;
+
+            int vSpaceLeft = heightSpecSize - shortAxisStartPadding - shortAxisEndPadding
+                    - (cellHeight * shortAxisCells);
+            if (numShortGaps > 0) {
+                mHeightGap = vSpaceLeft / numShortGaps;
+            } else {
+                mHeightGap = 0;
+            }
+        }
+        
+        int count = getChildCount();
+
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (mPortrait) {
+                lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, shortAxisStartPadding,
+                        longAxisStartPadding);
+            } else {
+                lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, longAxisStartPadding,
+                        shortAxisStartPadding);
+            }
+
+            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
+            int childheightMeasureSpec =
+                    MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
+            child.measure(childWidthMeasureSpec, childheightMeasureSpec);
+        }
+
+        setMeasuredDimension(widthSpecSize, heightSpecSize);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int count = getChildCount();
+
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+
+                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+
+                int childLeft = lp.x;
+                int childTop = lp.y;
+                child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
+            }
+        }
+    }
+
+    @Override
+    protected void setChildrenDrawingCacheEnabled(boolean enabled) {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View view = getChildAt(i);
+            view.setDrawingCacheEnabled(enabled);
+            // Update the drawing caches
+            view.buildDrawingCache();
+        }
+    }
+
+    @Override
+    protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
+        super.setChildrenDrawnWithCacheEnabled(enabled);
+    }
+
+    boolean acceptChildDrop(int x, int y, int cellHSpan, int cellVSpan, View cell) {
+        int[] cellXY = mCellXY;
+        pointToCellRounded(x, y, cellXY);
+        int cellX = cellXY[0];
+        int cellY = cellXY[1];
+
+        return findCell(cellX, cellY, cellHSpan, cellVSpan, cell) == null;
+    }
+
+    /**
+     * Finds the first View intersecting with the specified cell. If the cell is outside
+     * of the layout, this is returned.
+     *
+     * @param cellX The X location of the cell to test.
+     * @param cellY The Y location of the cell to test.
+     * @param cellHSpan The horizontal span of the cell to test.
+     * @param cellVSpan The vertical span of the cell to test.
+     * @param ignoreCell View to ignore during the test.
+     *
+     * @return Returns the first View intersecting with the specified cell, this if the cell
+     *         lies outside of this layout's grid or null if no View was found.
+     */
+    View findCell(int cellX, int cellY, int cellHSpan, int cellVSpan, View ignoreCell) {
+        if (cellX < 0 || cellX + cellHSpan > (mPortrait ? mShortAxisCells : mLongAxisCells) ||
+                cellY < 0 || cellY + cellVSpan > (mPortrait ? mLongAxisCells : mShortAxisCells)) {
+            return this;
+        }
+
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View view = getChildAt(i);
+            if (view == ignoreCell) {
+                continue;
+            }
+
+            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+            if (cellX < lp.cellX + lp.cellHSpan && lp.cellX < cellX + cellHSpan &&
+                    cellY < lp.cellY + lp.cellVSpan && lp.cellY < cellY + cellVSpan) {
+                return view;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Drop a child at the specified position
+     *
+     * @param child The child that is being dropped
+     * @param cellX The child's new x location
+     * @param cellY The child's new y location
+     */
+    void onDropChild(View child, int cellX, int cellY) {
+        int[] cellXY = mCellXY;
+        pointToCellRounded(cellX, cellY, cellXY);
+        LayoutParams lp = (LayoutParams) child.getLayoutParams();
+        lp.cellX = cellXY[0];
+        lp.cellY = cellXY[1];
+        lp.isDragging = false;
+        mDragRect.setEmpty();
+        child.requestLayout();
+        invalidate();
+    }
+
+    void onDropAborted(View child) {
+        if (child != null) {
+            ((LayoutParams) child.getLayoutParams()).isDragging = false;
+            invalidate();
+        }
+        mDragRect.setEmpty();
+    }
+
+    /**
+     * Start dragging the specified child
+     * 
+     * @param child The child that is being dragged
+     */
+    void onDragChild(View child) {
+        LayoutParams lp = (LayoutParams) child.getLayoutParams();
+        lp.isDragging = true;
+        mDragRect.setEmpty();
+    }
+    
+    /**
+     * Drag a child over the specified position
+     * 
+     * @param child The child that is being dropped
+     * @param cellX The child's new x cell location
+     * @param cellY The child's new y cell location 
+     */
+    void onDragOverChild(View child, int cellX, int cellY) {
+        int[] cellXY = mCellXY;
+        pointToCellRounded(cellX, cellY, cellXY);
+        LayoutParams lp = (LayoutParams) child.getLayoutParams();
+        cellToRect(cellXY[0], cellXY[1], lp.cellHSpan, lp.cellVSpan, mDragRect);
+        invalidate();
+    }
+    
+    /**
+     * Computes a bounding rectangle for a range of cells
+     *  
+     * @param cellX X coordinate of upper left corner expressed as a cell position
+     * @param cellY Y coordinate of upper left corner expressed as a cell position
+     * @param cellHSpan Width in cells 
+     * @param cellVSpan Height in cells
+     * @param dragRect Rectnagle into which to put the results
+     */
+    public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF dragRect) {
+        final boolean portrait = mPortrait;
+        final int cellWidth = mCellWidth;
+        final int cellHeight = mCellHeight;
+        final int widthGap = mWidthGap;
+        final int heightGap = mHeightGap;
+        
+        final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
+        final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
+        
+        int width = cellHSpan * cellWidth + ((cellHSpan - 1) * widthGap);
+        int height = cellVSpan * cellHeight + ((cellVSpan - 1) * heightGap);
+
+        int x = hStartPadding + cellX * (cellWidth + widthGap);
+        int y = vStartPadding + cellY * (cellHeight + heightGap);
+        
+        dragRect.set(x, y, x + width, y + height);
+    }
+    
+    /**
+     * Computes the required horizontal and vertical cell spans to always 
+     * fit the given rectangle.
+     *  
+     * @param width Width in pixels
+     * @param height Height in pixels
+     * @param Horizontal and vertical spans required
+     */
+    public int[] rectToCell(int width, int height) {
+        // Always assume we're working with the smallest span to make sure we
+        // reserve enough space in both orientations.
+        int actualWidth = mCellWidth + mWidthGap;
+        int actualHeight = mCellHeight + mHeightGap;
+        int smallerSize = Math.min(actualWidth, actualHeight);
+        
+        // Always round up to next largest cell
+        int spanX = (width + smallerSize) / smallerSize;
+        int spanY = (height + smallerSize) / smallerSize;
+        return new int[] { spanX, spanY };
+    }
+
+    /**
+     * Find the first vacant cell, if there is one.
+     *
+     * @param vacant Holds the x and y coordinate of the vacant cell
+     * @param spanX Horizontal cell span.
+     * @param spanY Vertical cell span.
+     * 
+     * @return True if a vacant cell was found
+     */
+    public boolean getVacantCell(int[] vacant, int spanX, int spanY) {
+        final boolean portrait = mPortrait;
+        final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
+        final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
+        final boolean[][] occupied = mOccupied;
+
+        findOccupiedCells(xCount, yCount, occupied);
+
+        return findVacantCell(vacant, spanX, spanY, xCount, yCount, occupied);
+    }
+
+    static boolean findVacantCell(int[] vacant, int spanX, int spanY,
+            int xCount, int yCount, boolean[][] occupied) {
+
+        for (int x = 0; x < xCount; x++) {
+            for (int y = 0; y < yCount; y++) {
+                boolean available = !occupied[x][y];
+out:            for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
+                    for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
+                        available = available && !occupied[i][j];
+                        if (!available) break out;
+                    }
+                }
+
+                if (available) {
+                    vacant[0] = x;
+                    vacant[1] = y;
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    boolean[] getOccupiedCells() {
+        final boolean portrait = mPortrait;
+        final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
+        final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
+        final boolean[][] occupied = mOccupied;
+
+        findOccupiedCells(xCount, yCount, occupied);
+
+        final boolean[] flat = new boolean[xCount * yCount];
+        for (int y = 0; y < yCount; y++) {
+            for (int x = 0; x < xCount; x++) {
+                flat[y * xCount + x] = occupied[x][y];
+            }
+        }
+
+        return flat;
+    }
+
+    private void findOccupiedCells(int xCount, int yCount, boolean[][] occupied) {
+        for (int x = 0; x < xCount; x++) {
+            for (int y = 0; y < yCount; y++) {
+                occupied[x][y] = false;
+            }
+        }
+
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            if (child instanceof Folder) {
+                continue;
+            }
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan && x < xCount; x++) {
+                for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan && y < yCount; y++) {
+                    occupied[x][y] = true;
+                }
+            }
+        }
+    }
+
+    @Override
+    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new CellLayout.LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof CellLayout.LayoutParams;
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return new CellLayout.LayoutParams(p);
+    }
+
+    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
+        /**
+         * Horizontal location of the item in the grid.
+         */
+        @ViewDebug.ExportedProperty
+        public int cellX;
+
+        /**
+         * Vertical location of the item in the grid.
+         */
+        @ViewDebug.ExportedProperty
+        public int cellY;
+
+        /**
+         * Number of cells spanned horizontally by the item.
+         */
+        @ViewDebug.ExportedProperty
+        public int cellHSpan;
+
+        /**
+         * Number of cells spanned vertically by the item.
+         */
+        @ViewDebug.ExportedProperty
+        public int cellVSpan;
+        
+        /**
+         * Is this item currently being dragged
+         */
+        public boolean isDragging;
+
+        // X coordinate of the view in the layout.
+        @ViewDebug.ExportedProperty
+        int x;
+        // Y coordinate of the view in the layout.
+        @ViewDebug.ExportedProperty
+        int y;
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+            cellHSpan = 1;
+            cellVSpan = 1;
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams source) {
+            super(source);
+            cellHSpan = 1;
+            cellVSpan = 1;
+        }
+        
+        public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) {
+            super(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
+            this.cellX = cellX;
+            this.cellY = cellY;
+            this.cellHSpan = cellHSpan;
+            this.cellVSpan = cellVSpan;
+        }
+
+        public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
+                int hStartPadding, int vStartPadding) {
+            
+            final int myCellHSpan = cellHSpan;
+            final int myCellVSpan = cellVSpan;
+            final int myCellX = cellX;
+            final int myCellY = cellY;
+            
+            width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
+                    leftMargin - rightMargin;
+            height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
+                    topMargin - bottomMargin;
+
+            x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
+            y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+        }
+    }
+
+    static final class CellInfo implements ContextMenu.ContextMenuInfo {
+        /**
+         * See View.AttachInfo.InvalidateInfo for futher explanations about
+         * the recycling mechanism. In this case, we recycle the vacant cells
+         * instances because up to several hundreds can be instanciated when
+         * the user long presses an empty cell.
+         */
+        static final class VacantCell {
+            int cellX;
+            int cellY;
+            int spanX;
+            int spanY;
+
+            // We can create up to 523 vacant cells on a 4x4 grid, 100 seems
+            // like a reasonable compromise given the size of a VacantCell and
+            // the fact that the user is not likely to touch an empty 4x4 grid
+            // very often 
+            private static final int POOL_LIMIT = 100;
+            private static final Object sLock = new Object();
+
+            private static int sAcquiredCount = 0;
+            private static VacantCell sRoot;
+
+            private VacantCell next;
+
+            static VacantCell acquire() {
+                synchronized (sLock) {
+                    if (sRoot == null) {
+                        return new VacantCell();
+                    }
+
+                    VacantCell info = sRoot;
+                    sRoot = info.next;
+                    sAcquiredCount--;
+
+                    return info;
+                }
+            }
+
+            void release() {
+                synchronized (sLock) {
+                    if (sAcquiredCount < POOL_LIMIT) {
+                        sAcquiredCount++;
+                        next = sRoot;
+                        sRoot = this;
+                    }
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX=" + spanX +
+                        ", spanY=" + spanY + "]";
+            }
+        }
+
+        View cell;
+        int cellX;
+        int cellY;
+        int spanX;
+        int spanY;
+        int screen;
+        boolean valid;
+
+        final ArrayList<VacantCell> vacantCells = new ArrayList<VacantCell>(VacantCell.POOL_LIMIT);
+        int maxVacantSpanX;
+        int maxVacantSpanXSpanY;
+        int maxVacantSpanY;
+        int maxVacantSpanYSpanX;
+        final Rect current = new Rect();
+
+        private void clearVacantCells() {
+            final ArrayList<VacantCell> list = vacantCells;
+            final int count = list.size();
+
+            for (int i = 0; i < count; i++) list.get(i).release();
+
+            list.clear();
+        }
+
+        void findVacantCellsFromOccupied(boolean[] occupied, int xCount, int yCount) {
+            if (cellX < 0 || cellY < 0) {
+                maxVacantSpanX = maxVacantSpanXSpanY = Integer.MIN_VALUE;
+                maxVacantSpanY = maxVacantSpanYSpanX = Integer.MIN_VALUE;
+                clearVacantCells();
+                return;
+            }
+
+            final boolean[][] unflattened = new boolean[xCount][yCount];
+            for (int y = 0; y < yCount; y++) {
+                for (int x = 0; x < xCount; x++) {
+                    unflattened[x][y] = occupied[y * xCount + x];
+                }
+            }
+            CellLayout.findIntersectingVacantCells(this, cellX, cellY, xCount, yCount, unflattened);
+        }
+
+        /**
+         * This method can be called only once! Calling #findVacantCellsFromOccupied will
+         * restore the ability to call this method.
+         *
+         * Finds the upper-left coordinate of the first rectangle in the grid that can
+         * hold a cell of the specified dimensions.
+         *
+         * @param cellXY The array that will contain the position of a vacant cell if such a cell
+         *               can be found.
+         * @param spanX The horizontal span of the cell we want to find.
+         * @param spanY The vertical span of the cell we want to find.
+         *
+         * @return True if a vacant cell of the specified dimension was found, false otherwise.
+         */
+        boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
+            final ArrayList<VacantCell> list = vacantCells;
+            final int count = list.size();
+
+            boolean found = false;
+
+            if (this.spanX >= spanX && this.spanY >= spanY) {
+                cellXY[0] = cellX;
+                cellXY[1] = cellY;
+                found = true;
+            }
+
+            // Look for an exact match first
+            for (int i = 0; i < count; i++) {
+                VacantCell cell = list.get(i);
+                if (cell.spanX == spanX && cell.spanY == spanY) {
+                    cellXY[0] = cell.cellX;
+                    cellXY[1] = cell.cellY;
+                    found = true;
+                    break;
+                }
+            }
+
+            // Look for the first cell large enough
+            for (int i = 0; i < count; i++) {
+                VacantCell cell = list.get(i);
+                if (cell.spanX >= spanX && cell.spanY >= spanY) {
+                    cellXY[0] = cell.cellX;
+                    cellXY[1] = cell.cellY;
+                    found = true;
+                    break;
+                }
+            }
+
+            clearVacantCells();
+
+            return found;
+        }
+
+        @Override
+        public String toString() {
+            return "Cell[view=" + (cell == null ? "null" : cell.getClass()) + ", x=" + cellX +
+                    ", y=" + cellY + "]";
+        }
+    }
+}
+
+
diff --git a/src/com/android/launcher/DeleteZone.java b/src/com/android/launcher/DeleteZone.java
new file mode 100644
index 0000000..f31a206
--- /dev/null
+++ b/src/com/android/launcher/DeleteZone.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.ImageView;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.TranslateAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AlphaAnimation;
+import android.graphics.RectF;
+import android.graphics.drawable.TransitionDrawable;
+
+public class DeleteZone extends ImageView implements DropTarget, DragController.DragListener {
+    private static final int ORIENTATION_HORIZONTAL = 1;
+    private static final int TRANSITION_DURATION = 250;
+    private static final int ANIMATION_DURATION = 200;
+
+    private final int[] mLocation = new int[2];
+    
+    private Launcher mLauncher;
+    private boolean mTrashMode;
+
+    private AnimationSet mInAnimation;
+    private AnimationSet mOutAnimation;
+    private Animation mHandleInAnimation;
+    private Animation mHandleOutAnimation;
+
+    private int mOrientation;
+    private DragLayer mDragLayer;
+
+    private final RectF mRegion = new RectF();
+    private TransitionDrawable mTransition;
+    private View mHandle;
+
+    public DeleteZone(Context context) {
+        super(context);
+    }
+
+    public DeleteZone(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DeleteZone(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeleteZone, defStyle, 0);
+        mOrientation = a.getInt(R.styleable.DeleteZone_direction, ORIENTATION_HORIZONTAL);
+        a.recycle();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mTransition = (TransitionDrawable) getBackground();
+    }
+
+    public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        return true;
+    }
+
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        final ItemInfo item = (ItemInfo) dragInfo;
+
+        if (item.container == -1) return;
+
+        final LauncherModel model = Launcher.getModel();
+        if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+            if (item instanceof LauncherGadgetInfo) {
+                model.removeDesktopGadget((LauncherGadgetInfo) item);
+            } else {
+                model.removeDesktopItem(item);
+            }
+        } else {
+            if (source instanceof UserFolder) {
+                final UserFolder userFolder = (UserFolder) source;
+                final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
+                model.removeUserFolderItem(userFolderInfo, item);
+            }
+        }
+        if (item instanceof UserFolderInfo) {
+            final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
+            LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
+            model.removeUserFolder(userFolderInfo);
+        } else if (item instanceof LauncherGadgetInfo) {
+            final LauncherGadgetInfo launcherGadgetInfo = (LauncherGadgetInfo)item;
+            final LauncherGadgetHost gadgetHost = mLauncher.getGadgetHost();
+            if (gadgetHost != null) {
+                gadgetHost.deleteGadgetId(launcherGadgetInfo.gadgetId);
+            }
+        }
+        LauncherModel.deleteItemFromDatabase(mLauncher, item);
+    }
+
+    public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        mTransition.reverseTransition(TRANSITION_DURATION);
+    }
+
+    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+    }
+
+    public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        mTransition.reverseTransition(TRANSITION_DURATION);
+    }
+
+    public void onDragStart(View v, DragSource source, Object info, int dragAction) {
+        final ItemInfo item = (ItemInfo) info;
+        if (item != null) {
+            mTrashMode = true;
+            createAnimations();
+            final int[] location = mLocation;
+            getLocationOnScreen(location);
+            mRegion.set(location[0], location[1], location[0] + mRight - mLeft,
+                    location[1] + mBottom - mTop);
+            mDragLayer.setDeleteRegion(mRegion);
+            mTransition.resetTransition();
+            startAnimation(mInAnimation);
+            mHandle.startAnimation(mHandleOutAnimation);
+            setVisibility(VISIBLE);
+        }
+    }
+
+    public void onDragEnd() {
+        if (mTrashMode) {
+            mTrashMode = false;
+            mDragLayer.setDeleteRegion(null);
+            startAnimation(mOutAnimation);
+            mHandle.startAnimation(mHandleInAnimation);
+            setVisibility(GONE);
+        }
+    }
+
+    private void createAnimations() {
+        if (mInAnimation == null) {
+            mInAnimation = new FastAnimationSet();
+            final AnimationSet animationSet = mInAnimation;
+            animationSet.setInterpolator(new AccelerateInterpolator());
+            animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
+            if (mOrientation == ORIENTATION_HORIZONTAL) {
+                animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
+                        Animation.RELATIVE_TO_SELF, 0.0f));
+            } else {
+                animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
+                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f));
+            }
+            animationSet.setDuration(ANIMATION_DURATION);
+        }
+        if (mHandleInAnimation == null) {
+            if (mOrientation == ORIENTATION_HORIZONTAL) {
+                mHandleInAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
+                        Animation.RELATIVE_TO_SELF, 0.0f);
+            } else {
+                mHandleInAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
+                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f);
+            }
+            mHandleInAnimation.setDuration(ANIMATION_DURATION);
+        }
+        if (mOutAnimation == null) {
+            mOutAnimation = new FastAnimationSet();
+            final AnimationSet animationSet = mOutAnimation;
+            animationSet.setInterpolator(new AccelerateInterpolator());
+            animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
+            if (mOrientation == ORIENTATION_HORIZONTAL) {
+                animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
+                        Animation.RELATIVE_TO_SELF, 1.0f));
+            } else {
+                animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
+                        0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f));
+            }
+            animationSet.setDuration(ANIMATION_DURATION);
+        }
+        if (mHandleOutAnimation == null) {
+            if (mOrientation == ORIENTATION_HORIZONTAL) {
+                mHandleOutAnimation = new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
+                        Animation.RELATIVE_TO_SELF, 1.0f);
+            } else {
+                mHandleOutAnimation = new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
+                        0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
+                        Animation.ABSOLUTE, 0.0f);
+            }
+            mHandleOutAnimation.setFillAfter(true);
+            mHandleOutAnimation.setDuration(ANIMATION_DURATION);
+        }
+    }
+
+    void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
+    }
+
+    void setDragController(DragLayer dragLayer) {
+        mDragLayer = dragLayer;
+    }
+
+    void setHandle(View view) {
+        mHandle = view;
+    }
+
+    private static class FastTranslateAnimation extends TranslateAnimation {
+        public FastTranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
+                int fromYType, float fromYValue, int toYType, float toYValue) {
+            super(fromXType, fromXValue, toXType, toXValue,
+                    fromYType, fromYValue, toYType, toYValue);
+        }
+
+        @Override
+        public boolean willChangeTransformationMatrix() {
+            return true;
+        }
+
+        @Override
+        public boolean willChangeBounds() {
+            return false;
+        }
+    }
+
+    private static class FastAnimationSet extends AnimationSet {
+        FastAnimationSet() {
+            super(false);
+        }
+
+        @Override
+        public boolean willChangeTransformationMatrix() {
+            return true;
+        }
+
+        @Override
+        public boolean willChangeBounds() {
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/launcher/DragController.java b/src/com/android/launcher/DragController.java
new file mode 100644
index 0000000..29cf15a
--- /dev/null
+++ b/src/com/android/launcher/DragController.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.view.View;
+
+/**
+ * Interface for initiating a drag within a view or across multiple views.
+ *
+ */
+public interface DragController {
+    
+    /**
+     * Interface to receive notifications when a drag starts or stops
+     */
+    interface DragListener {
+        
+        /**
+         * A drag has begun
+         * 
+         * @param v The view that is being dragged
+         * @param source An object representing where the drag originated
+         * @param info The data associated with the object that is being dragged
+         * @param dragAction The drag action: either {@link DragController#DRAG_ACTION_MOVE}
+         *        or {@link DragController#DRAG_ACTION_COPY}
+         */
+        void onDragStart(View v, DragSource source, Object info, int dragAction);
+        
+        /**
+         * The drag has eneded
+         */
+        void onDragEnd();
+    }
+    
+    /**
+     * Indicates the drag is a move.
+     */
+    public static int DRAG_ACTION_MOVE = 0;
+
+    /**
+     * Indicates the drag is a copy.
+     */
+    public static int DRAG_ACTION_COPY = 1;
+
+    /**
+     * Starts a drag
+     * 
+     * @param v The view that is being dragged
+     * @param source An object representing where the drag originated
+     * @param info The data associated with the object that is being dragged
+     * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
+     *        {@link #DRAG_ACTION_COPY}
+     */
+    void startDrag(View v, DragSource source, Object info, int dragAction);
+    
+    /**
+     * Sets the drag listner which will be notified when a drag starts or ends.
+     */
+    void setDragListener(DragListener l);
+    
+    /**
+     * Remove a previously installed drag listener.
+     */
+    void removeDragListener(DragListener l);
+}
diff --git a/src/com/android/launcher/DragLayer.java b/src/com/android/launcher/DragLayer.java
new file mode 100644
index 0000000..b542de6
--- /dev/null
+++ b/src/com/android/launcher/DragLayer.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Paint;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuff;
+import android.os.Vibrator;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.KeyEvent;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
+
+/**
+ * A ViewGroup that coordinated dragging across its dscendants
+ */
+public class DragLayer extends FrameLayout implements DragController {
+    private static final int SCROLL_DELAY = 600;
+    private static final int SCROLL_ZONE = 20;
+    private static final int VIBRATE_DURATION = 35;
+    private static final int ANIMATION_SCALE_UP_DURATION = 110;
+
+    private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
+
+    // Number of pixels to add to the dragged item for scaling
+    private static final float DRAG_SCALE = 24.0f;
+
+    private boolean mDragging = false;
+    private boolean mShouldDrop;
+    private float mLastMotionX;
+    private float mLastMotionY;
+    
+    /**
+     * The bitmap that is currently being dragged
+     */
+    private Bitmap mDragBitmap = null;
+    private View mOriginator;
+
+    private int mBitmapOffsetX;
+    private int mBitmapOffsetY;
+
+    /**
+     * X offset from where we touched on the cell to its upper-left corner
+     */
+    private float mTouchOffsetX;
+    
+    /**
+     * Y offset from where we touched on the cell to its upper-left corner
+     */
+    private float mTouchOffsetY;
+    
+    /**
+     * Utility rectangle
+     */
+    private Rect mDragRect = new Rect();
+    
+    /**
+     * Where the drag originated
+     */
+    private DragSource mDragSource;
+    
+    /**
+     * The data associated with the object being dragged
+     */
+    private Object mDragInfo;
+
+    private final Rect mRect = new Rect();    
+    private final int[] mDropCoordinates = new int[2];
+
+    private final Vibrator mVibrator = new Vibrator();
+    
+    private DragListener mListener;
+
+    private DragScroller mDragScroller;
+    
+    private static final int SCROLL_OUTSIDE_ZONE = 0;
+    private static final int SCROLL_WAITING_IN_ZONE = 1;
+
+    private static final int SCROLL_LEFT = 0;
+    private static final int SCROLL_RIGHT = 1;
+    
+    private int mScrollState = SCROLL_OUTSIDE_ZONE;
+
+    private ScrollRunnable mScrollRunnable = new ScrollRunnable();
+    private View mIgnoredDropTarget;
+
+    private RectF mDragRegion;
+    private boolean mEnteredRegion;
+    private DropTarget mLastDropTarget;
+
+    private final Paint mTrashPaint = new Paint();
+    private Paint mDragPaint;
+
+    private static final int ANIMATION_STATE_STARTING = 1;
+    private static final int ANIMATION_STATE_RUNNING = 2;
+    private static final int ANIMATION_STATE_DONE = 3;
+
+    private static final int ANIMATION_TYPE_SCALE = 1;
+
+    private float mAnimationFrom;
+    private float mAnimationTo;
+    private int mAnimationDuration;
+    private long mAnimationStartTime;
+    private int mAnimationType;
+    private int mAnimationState = ANIMATION_STATE_DONE;
+
+    private InputMethodManager mInputMethodManager;
+
+    /**
+     * Used to create a new DragLayer from XML.
+     *
+     * @param context The application's context.
+     * @param attrs The attribtues set containing the Workspace's customization values.
+     */
+    public DragLayer(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        final int srcColor = context.getResources().getColor(R.color.delete_color_filter);
+        mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP));
+    }
+
+    public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) {
+        if (PROFILE_DRAWING_DURING_DRAG) {
+            android.os.Debug.startMethodTracing("Launcher");
+        }
+
+        // Hide soft keyboard, if visible
+        if (mInputMethodManager == null) {
+            mInputMethodManager = (InputMethodManager)
+                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+        }
+        mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+
+        if (mListener != null) {
+            mListener.onDragStart(v, source, dragInfo, dragAction);
+        }
+
+        Rect r = mDragRect;
+        r.set(v.getScrollX(), v.getScrollY(), 0, 0);
+
+        offsetDescendantRectToMyCoords(v, r);
+        mTouchOffsetX = mLastMotionX - r.left;
+        mTouchOffsetY = mLastMotionY - r.top;
+
+        v.clearFocus();
+        v.setPressed(false);
+
+        boolean willNotCache = v.willNotCacheDrawing();
+        v.setWillNotCacheDrawing(false);
+        v.buildDrawingCache();
+
+        Bitmap viewBitmap = v.getDrawingCache();
+        int width = viewBitmap.getWidth();
+        int height = viewBitmap.getHeight();
+
+        Matrix scale = new Matrix();
+        float scaleFactor = v.getWidth();
+        scaleFactor = (scaleFactor + DRAG_SCALE) /scaleFactor;
+        scale.setScale(scaleFactor, scaleFactor);
+
+        mAnimationTo = 1.0f;
+        mAnimationFrom = 1.0f / scaleFactor;
+        mAnimationDuration = ANIMATION_SCALE_UP_DURATION;
+        mAnimationState = ANIMATION_STATE_STARTING;
+        mAnimationType = ANIMATION_TYPE_SCALE;
+
+        mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height, scale, true);
+        v.destroyDrawingCache();
+        v.setWillNotCacheDrawing(willNotCache);
+
+        final Bitmap dragBitmap = mDragBitmap;
+        mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2;
+        mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2;
+
+        if (dragAction == DRAG_ACTION_MOVE) {
+            v.setVisibility(GONE);
+        }
+
+        mDragPaint = null;
+        mDragging = true;
+        mShouldDrop = true;
+        mOriginator = v;
+        mDragSource = source;
+        mDragInfo = dragInfo;
+
+        mVibrator.vibrate(VIBRATE_DURATION);
+
+        mEnteredRegion = false;
+
+        invalidate();
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        return mDragging || super.dispatchKeyEvent(event);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+
+        if (mDragging && mDragBitmap != null) {
+            if (mAnimationState == ANIMATION_STATE_STARTING) {
+                mAnimationStartTime = SystemClock.uptimeMillis();
+                mAnimationState = ANIMATION_STATE_RUNNING;
+            }
+
+            if (mAnimationState == ANIMATION_STATE_RUNNING) {
+                float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) /
+                        mAnimationDuration;
+                if (normalized >= 1.0f) {
+                    mAnimationState = ANIMATION_STATE_DONE;
+                }
+                normalized = Math.min(normalized, 1.0f);
+                final float value = mAnimationFrom  + (mAnimationTo - mAnimationFrom) * normalized;
+
+                switch (mAnimationType) {
+                    case ANIMATION_TYPE_SCALE:
+                        final Bitmap dragBitmap = mDragBitmap;
+                        canvas.save();
+                        canvas.translate(mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
+                                mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
+                        canvas.translate((dragBitmap.getWidth() * (1.0f - value)) / 2,
+                                (dragBitmap.getHeight() * (1.0f - value)) / 2);
+                        canvas.scale(value, value);
+                        canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint);
+                        canvas.restore();
+                        break;
+                }
+            } else {
+                canvas.drawBitmap(mDragBitmap,
+                        mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
+                        mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint);
+            }
+        }
+    }
+
+    private void endDrag() {
+        if (mDragging) {
+            mDragging = false;
+            if (mDragBitmap != null) {
+                mDragBitmap.recycle();
+            }
+            if (mOriginator != null) {
+                mOriginator.setVisibility(VISIBLE);
+            }
+            if (mListener != null) {
+                mListener.onDragEnd();
+            }
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        final int action = ev.getAction();
+
+        final float x = ev.getX();
+        final float y = ev.getY();
+
+        switch (action) {
+            case MotionEvent.ACTION_MOVE:
+                break;
+
+            case MotionEvent.ACTION_DOWN:
+                // Remember location of down touch
+                mLastMotionX = x;
+                mLastMotionY = y;
+                mLastDropTarget = null;
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                if (mShouldDrop && drop(x, y)) {
+                    mShouldDrop = false;
+                }
+                endDrag();
+                break;
+        }
+
+        return mDragging;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (!mDragging) {
+            return false;
+        }
+
+        final int action = ev.getAction();
+        final float x = ev.getX();
+        final float y = ev.getY();
+
+        switch (action) {
+        case MotionEvent.ACTION_DOWN:
+
+            // Remember where the motion event started
+            mLastMotionX = x;
+            mLastMotionY = y;
+
+            if ((x < SCROLL_ZONE) || (x > getWidth() - SCROLL_ZONE)) {
+                mScrollState = SCROLL_WAITING_IN_ZONE;
+                postDelayed(mScrollRunnable, SCROLL_DELAY);
+            } else {
+                mScrollState = SCROLL_OUTSIDE_ZONE;
+            }
+
+            break;
+        case MotionEvent.ACTION_MOVE:
+            final int scrollX = mScrollX;
+            final int scrollY = mScrollY;
+
+            final float touchX = mTouchOffsetX;
+            final float touchY = mTouchOffsetY;
+
+            final int offsetX = mBitmapOffsetX;
+            final int offsetY = mBitmapOffsetY;
+
+            int left = (int) (scrollX + mLastMotionX - touchX - offsetX);
+            int top = (int) (scrollY + mLastMotionY - touchY - offsetY);
+
+            final Bitmap dragBitmap = mDragBitmap;
+            final int width = dragBitmap.getWidth();
+            final int height = dragBitmap.getHeight();
+
+            final Rect rect = mRect;
+            rect.set(left - 1, top - 1, left + width + 1, top + height + 1);
+
+            mLastMotionX = x;
+            mLastMotionY = y;
+
+            left = (int) (scrollX + x - touchX - offsetX);
+            top = (int) (scrollY + y - touchY - offsetY);
+
+            rect.union(left - 1, top - 1, left + width + 1, top + height + 1);
+            invalidate(rect);
+
+            final int[] coordinates = mDropCoordinates;
+            DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
+            if (dropTarget != null) {
+                if (mLastDropTarget == dropTarget) {
+                    dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],
+                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+                } else {
+                    if (mLastDropTarget != null) {
+                        mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
+                            (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+                    }
+                    dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],
+                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+                }
+            } else {
+                if (mLastDropTarget != null) {
+                    mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
+                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+                }
+            }
+            mLastDropTarget = dropTarget;
+
+            boolean inDragRegion = false;
+            if (mDragRegion != null) {
+                final RectF region = mDragRegion;
+                final boolean inRegion = region.contains(ev.getRawX(), ev.getRawY());
+                if (!mEnteredRegion && inRegion) {
+                    mDragPaint = mTrashPaint;
+                    mEnteredRegion = true;
+                    inDragRegion = true;
+                } else if (mEnteredRegion && !inRegion) {
+                    mDragPaint = null;
+                    mEnteredRegion = false;
+                }
+            }
+
+            if (!inDragRegion && x < SCROLL_ZONE) {
+                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
+                    mScrollState = SCROLL_WAITING_IN_ZONE;
+                    mScrollRunnable.setDirection(SCROLL_LEFT);
+                    postDelayed(mScrollRunnable, SCROLL_DELAY);
+                }
+            } else if (!inDragRegion && x > getWidth() - SCROLL_ZONE) {
+                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
+                    mScrollState = SCROLL_WAITING_IN_ZONE;
+                    mScrollRunnable.setDirection(SCROLL_RIGHT);
+                    postDelayed(mScrollRunnable, SCROLL_DELAY);
+                }
+            } else {
+                if (mScrollState == SCROLL_WAITING_IN_ZONE) {
+                    mScrollState = SCROLL_OUTSIDE_ZONE;
+                    mScrollRunnable.setDirection(SCROLL_RIGHT);
+                    removeCallbacks(mScrollRunnable);
+                }
+            }
+
+            break;
+        case MotionEvent.ACTION_UP:
+            removeCallbacks(mScrollRunnable);
+            if (mShouldDrop) {
+                drop(x, y);
+                mShouldDrop = false;
+            }
+            endDrag();
+
+            break;
+        case MotionEvent.ACTION_CANCEL:
+            endDrag();
+        }
+
+        return true;
+    }
+
+    private boolean drop(float x, float y) {
+        invalidate();
+
+        final int[] coordinates = mDropCoordinates;
+        DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
+
+        if (dropTarget != null) {
+            dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
+                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+            if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1],
+                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo)) {
+                dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
+                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
+                mDragSource.onDropCompleted((View) dropTarget, true);
+                return true;
+            } else {
+                mDragSource.onDropCompleted((View) dropTarget, false);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
+        return findDropTarget(this, x, y, dropCoordinates);
+    }
+
+    private DropTarget findDropTarget(ViewGroup container, int x, int y, int[] dropCoordinates) {
+        final Rect r = mDragRect;
+        final int count = container.getChildCount();
+        final int scrolledX = x + container.getScrollX();
+        final int scrolledY = y + container.getScrollY();
+        final View ignoredDropTarget = mIgnoredDropTarget;
+
+        for (int i = count - 1; i >= 0; i--) {
+            final View child = container.getChildAt(i);
+            if (child.getVisibility() == VISIBLE && child != ignoredDropTarget) {
+                child.getHitRect(r);
+                if (r.contains(scrolledX, scrolledY)) {
+                    DropTarget target = null;
+                    if (child instanceof ViewGroup) {
+                        x = scrolledX - child.getLeft();
+                        y = scrolledY - child.getTop();
+                        target = findDropTarget((ViewGroup) child, x, y, dropCoordinates);
+                    }
+                    if (target == null) {
+                        if (child instanceof DropTarget) {
+                            dropCoordinates[0] = x;
+                            dropCoordinates[1] = y;
+                            return (DropTarget) child;
+                        }
+                    } else {
+                        return target;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public void setDragScoller(DragScroller scroller) {
+        mDragScroller = scroller;
+    }
+
+    public void setDragListener(DragListener l) {
+        mListener = l;
+    }
+
+    public void removeDragListener(DragListener l) {
+        mListener = null;   
+    }
+
+    /**
+     * Specifies the view that must be ignored when looking for a drop target.
+     *
+     * @param view The view that will not be taken into account while looking
+     *        for a drop target.
+     */
+    void setIgnoredDropTarget(View view) {
+        mIgnoredDropTarget = view;
+    }
+
+    /**
+     * Specifies the delete region.
+     *
+     * @param region The rectangle in screen coordinates of the delete region.
+     */
+    void setDeleteRegion(RectF region) {
+        mDragRegion = region;
+    }
+
+    private class ScrollRunnable implements Runnable {
+        private int mDirection;
+
+        ScrollRunnable() {
+        }
+
+        public void run() {
+            if (mDragScroller != null) {
+                if (mDirection == SCROLL_LEFT) {
+                    mDragScroller.scrollLeft();
+                } else {
+                    mDragScroller.scrollRight();
+                }
+                mScrollState = SCROLL_OUTSIDE_ZONE;
+            }
+        }
+
+        void setDirection(int direction) {
+            mDirection = direction;
+        }
+    }    
+}
diff --git a/src/com/android/launcher/DragScroller.java b/src/com/android/launcher/DragScroller.java
new file mode 100644
index 0000000..2c18a79
--- /dev/null
+++ b/src/com/android/launcher/DragScroller.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+/**
+ * Handles scrolling while dragging
+ *
+ */
+public interface DragScroller {
+    void scrollLeft();
+    void scrollRight();
+}
diff --git a/src/com/android/launcher/DragSource.java b/src/com/android/launcher/DragSource.java
new file mode 100644
index 0000000..0ac25bb
--- /dev/null
+++ b/src/com/android/launcher/DragSource.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.view.View;
+
+/**
+ * Interface defining an object that can originate a drag.
+ *
+ */
+public interface DragSource {
+    void setDragger(DragController dragger);
+    void onDropCompleted(View target, boolean success);
+}
diff --git a/src/com/android/launcher/DropTarget.java b/src/com/android/launcher/DropTarget.java
new file mode 100644
index 0000000..8129089
--- /dev/null
+++ b/src/com/android/launcher/DropTarget.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+/**
+ * Interface defining an object that can receive a drag.
+ *
+ */
+public interface DropTarget {
+
+    /**
+     * Handle an object being dropped on the DropTarget
+     * 
+     * @param source DragSource where the drag started
+     * @param x X coordinate of the drop location
+     * @param y Y coordinate of the drop location
+     * @param xOffset Horizontal offset with the object being dragged where the original touch happened
+     * @param yOffset Vertical offset with the object being dragged where the original touch happened
+     * @param dragInfo Data associated with the object being dragged
+     * 
+     */
+    void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
+    
+    void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
+
+    void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
+
+    void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
+
+    /**
+     * Indicates whether a drop action can occur at the specified location. The method
+     * {@link #onDrop(DragSource, int, int, int, int, Object)} will be invoked on this
+     * drop target only if this method returns true. 
+     *
+     * @param source DragSource where the drag started
+     * @param x X coordinate of the drop location
+     * @param y Y coordinate of the drop location
+     * @param xOffset Horizontal offset with the object being dragged where the original touch happened
+     * @param yOffset Vertical offset with the object being dragged where the original touch happened
+     * @param dragInfo Data associated with the object being dragged
+     *
+     * return True if the drop is accepted, false otherwise.
+     */
+    boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
+}
diff --git a/src/com/android/launcher/FastBitmapDrawable.java b/src/com/android/launcher/FastBitmapDrawable.java
new file mode 100644
index 0000000..170f1ad
--- /dev/null
+++ b/src/com/android/launcher/FastBitmapDrawable.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.graphics.drawable.Drawable;
+import android.graphics.PixelFormat;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+
+class FastBitmapDrawable extends Drawable {
+    private Bitmap mBitmap;
+
+    FastBitmapDrawable(Bitmap b) {
+        mBitmap = b;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mBitmap.getWidth();
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mBitmap.getHeight();
+    }
+
+    @Override
+    public int getMinimumWidth() {
+        return mBitmap.getWidth();
+    }
+
+    @Override
+    public int getMinimumHeight() {
+        return mBitmap.getHeight();
+    }
+
+    public Bitmap getBitmap() {
+        return mBitmap;
+    }
+}
diff --git a/src/com/android/launcher/Folder.java b/src/com/android/launcher/Folder.java
new file mode 100644
index 0000000..bcbccf7
--- /dev/null
+++ b/src/com/android/launcher/Folder.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.AbsListView;
+import android.widget.ListAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+
+/**
+ * Represents a set of icons chosen by the user or generated by the system.
+ */
+public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
+        OnItemClickListener, OnClickListener, View.OnLongClickListener {
+
+    protected AbsListView mContent;
+    protected DragController mDragger;
+    
+    protected Launcher mLauncher;
+
+    protected Button mCloseButton;
+    
+    protected FolderInfo mInfo;
+    
+    /**
+     * Which item is being dragged
+     */
+    protected ApplicationInfo mDragItem;
+    private boolean mCloneInfo;
+
+    /**
+     * Used to inflate the Workspace from XML.
+     *
+     * @param context The application's context.
+     * @param attrs The attribtues set containing the Workspace's customization values.
+     */
+    public Folder(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setAlwaysDrawnWithCacheEnabled(false);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mContent = (AbsListView) findViewById(R.id.content);
+        mContent.setOnItemClickListener(this);
+        mContent.setOnItemLongClickListener(this);
+        
+        mCloseButton = (Button) findViewById(R.id.close);
+        mCloseButton.setOnClickListener(this);
+        mCloseButton.setOnLongClickListener(this);
+    }
+    
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
+        mLauncher.startActivitySafely(app.intent);
+    }
+
+    public void onClick(View v) {
+        mLauncher.closeFolder(this);
+    }
+
+    public boolean onLongClick(View v) {
+        mLauncher.closeFolder(this);
+        mLauncher.showRenameDialog(mInfo);
+        return true;
+    }
+
+    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+        if (!view.isInTouchMode()) {
+            return false;
+        }
+
+        ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
+        if (mCloneInfo) {
+            app = new ApplicationInfo(app);
+        }
+
+        mDragger.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
+        mLauncher.closeFolder(this);
+        mDragItem = app;
+
+        return true;
+    }
+
+    void setCloneInfo(boolean cloneInfo) {
+        mCloneInfo = cloneInfo;
+    }
+
+    public void setDragger(DragController dragger) {
+        mDragger = dragger;
+    }
+
+    public void onDropCompleted(View target, boolean success) {
+    }
+
+    /**
+     * Sets the adapter used to populate the content area. The adapter must only
+     * contains ApplicationInfo items.
+     *
+     * @param adapter The list of applications to display in the folder.
+     */
+    void setContentAdapter(ListAdapter adapter) {
+        mContent.setAdapter(adapter);
+    }
+
+    void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
+    }
+    
+    /**
+     * @return the FolderInfo object associated with this folder
+     */
+    FolderInfo getInfo() {
+        return mInfo;
+    }
+
+    // When the folder opens, we need to refresh the GridView's selection by
+    // forcing a layout
+    void onOpen() {
+        mContent.requestLayout();
+    }
+
+    void onClose() {
+        final Workspace workspace = mLauncher.getWorkspace();
+        workspace.getChildAt(workspace.getCurrentScreen()).requestFocus();
+    }
+
+    void bind(FolderInfo info) {
+        mInfo = info;
+        mCloseButton.setText(info.title);
+    }
+}
diff --git a/src/com/android/launcher/FolderIcon.java b/src/com/android/launcher/FolderIcon.java
new file mode 100644
index 0000000..667f92e
--- /dev/null
+++ b/src/com/android/launcher/FolderIcon.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+/**
+ * An icon that can appear on in the workspace representing an {@link UserFolder}.
+ */
+public class FolderIcon extends BubbleTextView implements DropTarget {
+    private UserFolderInfo mInfo;
+    private Launcher mLauncher;
+    private Drawable mCloseIcon;
+    private Drawable mOpenIcon;
+
+    public FolderIcon(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public FolderIcon(Context context) {
+        super(context);
+    }
+
+    static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
+            UserFolderInfo folderInfo) {
+
+        FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
+
+        final Resources resources = launcher.getResources();
+        Drawable d = resources.getDrawable(R.drawable.ic_launcher_folder);
+        d = Utilities.createIconThumbnail(d, launcher);
+        icon.mCloseIcon = d;
+        icon.mOpenIcon = resources.getDrawable(R.drawable.ic_launcher_folder_open);
+        icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
+        icon.setText(folderInfo.title);
+        icon.setTag(folderInfo);
+        icon.setOnClickListener(launcher);
+        icon.mInfo = folderInfo;
+        icon.mLauncher = launcher;
+        
+        return icon;
+    }
+
+    public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        final ItemInfo item = (ItemInfo) dragInfo;
+        final int itemType = item.itemType;
+        return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+                itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
+                && item.container != mInfo.id;
+    }
+
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        final ApplicationInfo item = (ApplicationInfo) dragInfo;
+        // TODO: update open folder that is looking at this data
+        mInfo.add(item);
+        LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
+    }
+
+    public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        setCompoundDrawablesWithIntrinsicBounds(null, mOpenIcon, null, null);
+    }
+
+    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+    }
+
+    public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
+    }
+}
diff --git a/src/com/android/launcher/FolderInfo.java b/src/com/android/launcher/FolderInfo.java
new file mode 100644
index 0000000..a58675b
--- /dev/null
+++ b/src/com/android/launcher/FolderInfo.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+
+/**
+ * Represents a folder containing shortcuts or apps.
+ */
+class FolderInfo extends ItemInfo {
+    
+    /**
+     * Whether this folder has been opened
+     */
+    boolean opened;
+
+    /**
+     * The folder name.
+     */
+    CharSequence title;
+}
diff --git a/src/com/android/launcher/HandleView.java b/src/com/android/launcher/HandleView.java
new file mode 100644
index 0000000..9afe41c
--- /dev/null
+++ b/src/com/android/launcher/HandleView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.ImageView;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.KeyEvent;
+
+public class HandleView extends ImageView {
+    private static final int ORIENTATION_HORIZONTAL = 1;
+
+    private Launcher mLauncher;
+    private int mOrientation = ORIENTATION_HORIZONTAL;
+
+    public HandleView(Context context) {
+        super(context);
+    }
+
+    public HandleView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public HandleView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HandleView, defStyle, 0);
+        mOrientation = a.getInt(R.styleable.HandleView_direction, ORIENTATION_HORIZONTAL);
+        a.recycle();
+    }
+
+    @Override
+    public View focusSearch(int direction) {
+        View newFocus = super.focusSearch(direction);
+        if (newFocus == null && mLauncher.isDrawerDown()) {
+            final Workspace workspace = mLauncher.getWorkspace();
+            workspace.dispatchUnhandledMove(null, direction);
+            return (mOrientation == ORIENTATION_HORIZONTAL && direction == FOCUS_DOWN) ?
+                    this : workspace;
+        }
+        return newFocus;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        final boolean handled = super.onKeyDown(keyCode, event);
+
+        if (!handled && !mLauncher.isDrawerDown() && !isDirectionKey(keyCode)) {
+            return mLauncher.getApplicationsGrid().onKeyDown(keyCode, event);
+        }
+
+        return handled;
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        final boolean handled = super.onKeyUp(keyCode, event);
+
+        if (!handled && !mLauncher.isDrawerDown() && !isDirectionKey(keyCode)) {
+            return mLauncher.getApplicationsGrid().onKeyUp(keyCode, event);
+        }
+
+        return handled;
+    }
+
+    private static boolean isDirectionKey(int keyCode) {
+        return keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_LEFT ||
+                keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_UP;
+    }
+
+    void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
+    }
+}
diff --git a/src/com/android/launcher/InstallShortcutReceiver.java b/src/com/android/launcher/InstallShortcutReceiver.java
new file mode 100644
index 0000000..a1e954a
--- /dev/null
+++ b/src/com/android/launcher/InstallShortcutReceiver.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ContentResolver;
+import android.database.Cursor;
+
+public class InstallShortcutReceiver extends BroadcastReceiver {
+    private final int[] mCoordinates = new int[2];
+
+    public void onReceive(Context context, Intent data) {
+        int screen = Launcher.getScreen();
+
+        if (!installShortcut(context, data, screen)) {
+            // The target screen is full, let's try the other screens
+            for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
+                if (i != screen && installShortcut(context, data, i)) break;
+            }
+        }
+    }
+
+    private boolean installShortcut(Context context, Intent data, int screen) {
+        if (findEmptyCell(context, mCoordinates, screen)) {
+            CellLayout.CellInfo cell = new CellLayout.CellInfo();
+            cell.cellX = mCoordinates[0];
+            cell.cellY = mCoordinates[1];
+            cell.screen = screen;
+
+            Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+            String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+
+            if (intent.getAction() == null) {
+                intent.setAction(Intent.ACTION_VIEW);
+            }
+
+            // By default, we allow for duplicate entries (located in
+            // different places)
+            boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
+            if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
+                Launcher.addShortcut(context, data, cell, true);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private static boolean findEmptyCell(Context context, int[] xy, int screen) {
+        final int xCount = Launcher.NUMBER_CELLS_X;
+        final int yCount = Launcher.NUMBER_CELLS_Y;
+
+        boolean[][] occupied = new boolean[xCount][yCount];
+
+        final ContentResolver cr = context.getContentResolver();
+        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
+            new String[] { LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
+                    LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY },
+            LauncherSettings.Favorites.SCREEN + "=?",
+            new String[] { String.valueOf(screen) }, null);
+
+        final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+        final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+        final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
+        final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
+
+        try {
+            while (c.moveToNext()) {
+                int cellX = c.getInt(cellXIndex);
+                int cellY = c.getInt(cellYIndex);
+                int spanX = c.getInt(spanXIndex);
+                int spanY = c.getInt(spanYIndex);
+
+                for (int x = cellX; x < cellX + spanX && x < xCount; x++) {
+                    for (int y = cellY; y < cellY + spanY && y < yCount; y++) {
+                        occupied[x][y] = true;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            return false;
+        } finally {
+            c.close();
+        }
+
+        return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied);
+    }
+}
diff --git a/src/com/android/launcher/ItemInfo.java b/src/com/android/launcher/ItemInfo.java
new file mode 100644
index 0000000..8899f44
--- /dev/null
+++ b/src/com/android/launcher/ItemInfo.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import android.content.ContentValues;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+/**
+ * Represents an item in the launcher.
+ */
+class ItemInfo {
+    
+    static final int NO_ID = -1;
+    
+    /**
+     * The id in the settings database for this item
+     */
+    long id = NO_ID;
+    
+    /**
+     * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, or
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_GADGET}.
+     */
+    int itemType;
+    
+    /**
+     * The id of the container that holds this item. For the desktop, this will be 
+     * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. For the all applications folder it
+     * will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders
+     * it will be the id of the folder.
+     */
+    long container = NO_ID;
+    
+    /**
+     * Iindicates the screen in which the shortcut appears.
+     */
+    int screen = -1;
+    
+    /**
+     * Indicates the X position of the associated cell.
+     */
+    int cellX = -1;
+
+    /**
+     * Indicates the Y position of the associated cell.
+     */
+    int cellY = -1;
+
+    /**
+     * Indicates the X cell span.
+     */
+    int spanX = 1;
+
+    /**
+     * Indicates the Y cell span.
+     */
+    int spanY = 1;
+
+    ItemInfo() {
+    }
+
+    ItemInfo(ItemInfo info) {
+        id = info.id;
+        cellX = info.cellX;
+        cellY = info.cellY;
+        spanX = info.spanX;
+        spanY = info.spanY;
+        screen = info.screen;
+        itemType = info.itemType;
+        container = info.container;
+    }
+
+    /**
+     * Write the fields of this item to the DB
+     * 
+     * @param values
+     */
+    void onAddToDatabase(ContentValues values) { 
+        values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType);
+        values.put(LauncherSettings.Favorites.CONTAINER, container);
+        values.put(LauncherSettings.Favorites.SCREEN, screen);
+        values.put(LauncherSettings.Favorites.CELLX, cellX);
+        values.put(LauncherSettings.Favorites.CELLY, cellY);
+        values.put(LauncherSettings.Favorites.SPANX, spanX);
+        values.put(LauncherSettings.Favorites.SPANY, spanY);
+    }
+
+    static void writeBitmap(ContentValues values, Bitmap bitmap) {
+        if (bitmap != null) {
+            // Try go guesstimate how much space the icon will take when serialized
+            // to avoid unnecessary allocations/copies during the write.
+            int size = bitmap.getWidth() * bitmap.getHeight() * 4;
+            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
+            try {
+                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+                out.flush();
+                out.close();
+
+                values.put(LauncherSettings.Favorites.ICON, out.toByteArray());
+            } catch (IOException e) {
+                Log.w("Favorite", "Could not write icon");
+            }
+        }
+    }
+    
+}
diff --git a/src/com/android/launcher/Launcher.java b/src/com/android/launcher/Launcher.java
new file mode 100644
index 0000000..e88e55e
--- /dev/null
+++ b/src/com/android/launcher/Launcher.java
@@ -0,0 +1,1888 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Application;
+import android.app.Dialog;
+import android.app.SearchManager;
+import android.app.StatusBarManager;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+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.database.ContentObserver;
+import android.gadget.GadgetProviderInfo;
+import android.gadget.GadgetManager;
+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.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.Message;
+import android.provider.*;
+import android.telephony.PhoneNumberUtils;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.method.TextKeyListener;
+import android.util.Log;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.View.OnLongClickListener;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.GridView;
+import android.widget.SlidingDrawer;
+import android.app.IWallpaperService;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Default launcher application.
+ */
+public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener {
+    static final String LOG_TAG = "Launcher";
+    static final boolean LOGD = false;
+
+    private static final boolean PROFILE_STARTUP = false;
+    private static final boolean DEBUG_USER_INTERFACE = false;
+
+    private static final int WALLPAPER_SCREENS_SPAN = 2;
+
+    private static final int MENU_GROUP_ADD = 1;
+    private static final int MENU_ADD = Menu.FIRST + 1;
+    private static final int MENU_WALLPAPER_SETTINGS = MENU_ADD + 1;
+    private static final int MENU_SEARCH = MENU_WALLPAPER_SETTINGS + 1;
+    private static final int MENU_NOTIFICATIONS = MENU_SEARCH + 1;
+    private static final int MENU_SETTINGS = MENU_NOTIFICATIONS + 1;
+
+    private static final int REQUEST_CREATE_SHORTCUT = 1;
+    private static final int REQUEST_CREATE_LIVE_FOLDER = 4;
+    private static final int REQUEST_CREATE_GADGET = 5;
+    private static final int REQUEST_PICK_APPLICATION = 6;
+    private static final int REQUEST_PICK_SHORTCUT = 7;
+    private static final int REQUEST_PICK_LIVE_FOLDER = 8;
+    private static final int REQUEST_PICK_GADGET = 9;
+
+    static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
+
+    static final int SCREEN_COUNT = 3;
+    static final int DEFAULT_SCREN = 1;
+    static final int NUMBER_CELLS_X = 4;
+    static final int NUMBER_CELLS_Y = 4;    
+
+    private static final int DIALOG_CREATE_SHORTCUT = 1;
+    static final int DIALOG_RENAME_FOLDER = 2;    
+
+    private static final String PREFERENCES = "launcher";
+    private static final String KEY_LOCALE = "locale";
+    private static final String KEY_MCC = "mcc";
+    private static final String KEY_MNC = "mnc";
+
+    // Type: int
+    private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
+    // Type: boolean
+    private static final String RUNTIME_STATE_ALL_APPS_FOLDER = "launcher.all_apps_folder";
+    // Type: long
+    private static final String RUNTIME_STATE_USER_FOLDERS = "launcher.user_folder";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cellX";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cellY";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_spanX";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_spanY";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_COUNT_X = "launcher.add_countX";
+    // Type: int
+    private static final String RUNTIME_STATE_PENDING_ADD_COUNT_Y = "launcher.add_countY";
+    // Type: int[]
+    private static final String RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS = "launcher.add_occupied_cells";
+    // Type: boolean
+    private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";
+    // Type: long
+    private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";
+
+    private static LauncherModel sModel;
+
+    private static Bitmap sWallpaper;
+
+    private static final Object sLock = new Object();
+    private static int sScreen = DEFAULT_SCREN;
+
+    private static WallpaperIntentReceiver sWallpaperReceiver;
+
+    private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
+    private final ContentObserver mObserver = new FavoritesChangeObserver();
+
+    private LayoutInflater mInflater;
+
+    private DragLayer mDragLayer;
+    private Workspace mWorkspace;
+    
+    private GadgetManager mGadgetManager;
+    private LauncherGadgetHost mGadgetHost;
+    
+    static final int GADGET_HOST_ID = 1024;
+    
+    private CellLayout.CellInfo mAddItemCellInfo;
+    private CellLayout.CellInfo mMenuAddInfo;
+    private final int[] mCellCoordinates = new int[2];
+    private FolderInfo mFolderInfo;
+
+    private SlidingDrawer mDrawer;
+    private TransitionDrawable mHandleIcon;
+    private AllAppsGridView mAllAppsGrid;
+
+    private boolean mDesktopLocked = true;
+    private Bundle mSavedState;
+
+    private SpannableStringBuilder mDefaultKeySsb = null;
+
+    private boolean mDestroyed;
+
+    private boolean mRestoring;
+    private boolean mWaitingForResult;
+    private boolean mLocaleChanged;
+
+    private Bundle mSavedInstanceState;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mInflater = getLayoutInflater();
+        
+        mGadgetManager = GadgetManager.getInstance(this);
+        
+        mGadgetHost = new LauncherGadgetHost(this, GADGET_HOST_ID);
+        mGadgetHost.startListening();
+        
+        if (PROFILE_STARTUP) {
+            android.os.Debug.startMethodTracing("/sdcard/launcher");
+        }
+
+        checkForLocaleChange();
+        setWallpaperDimension();
+
+        if (sModel == null) {
+            sModel = new LauncherModel();
+        }
+
+        setContentView(R.layout.launcher);
+        setupViews();
+
+        registerIntentReceivers();
+        registerContentObservers();
+
+        mSavedState = savedInstanceState;
+        restoreState(mSavedState);
+
+        if (PROFILE_STARTUP) {
+            android.os.Debug.stopMethodTracing();
+        }
+
+        if (!mRestoring) {
+            startLoaders();
+        }
+
+        // For handling default keys
+        mDefaultKeySsb = new SpannableStringBuilder();
+        Selection.setSelection(mDefaultKeySsb, 0);
+    }
+    
+    private void checkForLocaleChange() {
+        final SharedPreferences preferences = getSharedPreferences(PREFERENCES, MODE_PRIVATE);
+        final Configuration configuration = getResources().getConfiguration();
+
+        final String previousLocale = preferences.getString(KEY_LOCALE, null);
+        final String locale = configuration.locale.toString();
+
+        final int previousMcc = preferences.getInt(KEY_MCC, -1);
+        final int mcc = configuration.mcc;
+
+        final int previousMnc = preferences.getInt(KEY_MNC, -1);
+        final int mnc = configuration.mnc;
+
+        mLocaleChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;
+
+        if (mLocaleChanged) {
+            final SharedPreferences.Editor editor = preferences.edit();
+            editor.putString(KEY_LOCALE, locale);
+            editor.putInt(KEY_MCC, mcc);
+            editor.putInt(KEY_MNC, mnc);
+            editor.commit();
+        }
+    }
+
+    static int getScreen() {
+        synchronized (sLock) {
+            return sScreen;
+        }
+    }
+
+    static void setScreen(int screen) {
+        synchronized (sLock) {
+            sScreen = screen;
+        }
+    }
+
+    private void startLoaders() {
+        sModel.loadApplications(true, this, mLocaleChanged);
+        sModel.loadUserItems(!mLocaleChanged, this, mLocaleChanged, true);
+        mRestoring = false;
+    }
+
+    private void setWallpaperDimension() {
+        IBinder binder = ServiceManager.getService(WALLPAPER_SERVICE);
+        IWallpaperService wallpaperService = IWallpaperService.Stub.asInterface(binder);
+
+        Display display = getWindowManager().getDefaultDisplay();
+        boolean isPortrait = display.getWidth() < display.getHeight();
+
+        final int width = isPortrait ? display.getWidth() : display.getHeight();
+        final int height = isPortrait ? display.getHeight() : display.getWidth();
+        try {
+            wallpaperService.setDimensionHints(width * WALLPAPER_SCREENS_SPAN, height);
+        } catch (RemoteException e) {
+            // System is dead!
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        // The pattern used here is that a user PICKs a specific application,
+        // which, depending on the target, might need to CREATE the actual target.
+        
+        // For example, the user would PICK_SHORTCUT for "Music playlist", and we
+        // launch over to the Music app to actually CREATE_SHORTCUT.
+        
+        if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
+            switch (requestCode) {
+                case REQUEST_PICK_APPLICATION:
+                    completeAddApplication(this, data, mAddItemCellInfo, !mDesktopLocked);
+                    break;
+                case REQUEST_PICK_SHORTCUT:
+                    addShortcut(data);
+                    break;
+                case REQUEST_CREATE_SHORTCUT:
+                    completeAddShortcut(data, mAddItemCellInfo, !mDesktopLocked);
+                    break;
+                case REQUEST_PICK_LIVE_FOLDER:
+                    addLiveFolder(data);
+                    break;
+                case REQUEST_CREATE_LIVE_FOLDER:
+                    completeAddLiveFolder(data, mAddItemCellInfo, !mDesktopLocked);
+                    break;
+                case REQUEST_PICK_GADGET:
+                    addGadget(data);
+                    break;
+                case REQUEST_CREATE_GADGET:
+                    completeAddGadget(data, mAddItemCellInfo, !mDesktopLocked);
+                    break;
+            }
+        } else if (requestCode == REQUEST_PICK_GADGET &&
+                resultCode == RESULT_CANCELED && data != null) {
+            // Clean up the gadgetId if we canceled
+            int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1);
+            if (gadgetId != -1) {
+                mGadgetHost.deleteGadgetId(gadgetId);
+            }
+        }
+        mWaitingForResult = false;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (mRestoring) {
+            startLoaders();
+        }
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        boolean handled = super.onKeyUp(keyCode, event);
+        if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+            handled = mWorkspace.snapToSearch();
+            if (handled) closeDrawer(true);
+        }
+        return handled;
+    }
+
+    private boolean acceptFilter() {
+        final InputMethodManager inputManager = (InputMethodManager)
+                getSystemService(Context.INPUT_METHOD_SERVICE);
+        return !inputManager.isFullscreenMode();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        boolean handled = super.onKeyDown(keyCode, event);
+        if (!handled && acceptFilter() && keyCode != KeyEvent.KEYCODE_ENTER) {
+            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);
+
+                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;
+            }
+        }
+
+        return handled;
+    }
+
+    /**
+     * Restores the previous state, if it exists.
+     *
+     * @param savedState The previous state.
+     */
+    private void restoreState(Bundle savedState) {
+        if (savedState == null) {
+            return;
+        }
+
+        final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
+        if (currentScreen > -1) {
+            mWorkspace.setCurrentScreen(currentScreen);
+        }
+
+        final int addScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);
+        if (addScreen > -1) {
+            mAddItemCellInfo = new CellLayout.CellInfo();
+            final CellLayout.CellInfo addItemCellInfo = mAddItemCellInfo;
+            addItemCellInfo.valid = true;
+            addItemCellInfo.screen = addScreen;
+            addItemCellInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);
+            addItemCellInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);
+            addItemCellInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);
+            addItemCellInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);
+            addItemCellInfo.findVacantCellsFromOccupied(
+                    savedState.getBooleanArray(RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS),
+                    savedState.getInt(RUNTIME_STATE_PENDING_ADD_COUNT_X),
+                    savedState.getInt(RUNTIME_STATE_PENDING_ADD_COUNT_Y));
+            mRestoring = true;
+        }
+
+        boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);
+        if (renameFolder) {
+            long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);
+            mFolderInfo = sModel.getFolderById(this, id);
+            mRestoring = true;
+        }
+    }
+
+    /**
+     * Finds all the views we need and configure them properly.
+     */
+    private void setupViews() {
+        mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
+        final DragLayer dragLayer = mDragLayer;
+
+        mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
+        final Workspace workspace = mWorkspace;
+
+        mDrawer = (SlidingDrawer) dragLayer.findViewById(R.id.drawer);
+        final SlidingDrawer drawer = mDrawer;
+
+        mAllAppsGrid = (AllAppsGridView) drawer.getContent();
+        final AllAppsGridView grid = mAllAppsGrid;
+
+        final DeleteZone deleteZone = (DeleteZone) dragLayer.findViewById(R.id.delete_zone);
+
+        final HandleView handleIcon = (HandleView) drawer.findViewById(R.id.all_apps);
+        handleIcon.setLauncher(this);
+        mHandleIcon = (TransitionDrawable) handleIcon.getDrawable();
+        mHandleIcon.setCrossFadeEnabled(true);
+
+        drawer.lock();
+        final DrawerManager drawerManager = new DrawerManager();
+        drawer.setOnDrawerOpenListener(drawerManager);
+        drawer.setOnDrawerCloseListener(drawerManager);
+        drawer.setOnDrawerScrollListener(drawerManager);
+
+        grid.setTextFilterEnabled(true);
+        grid.setDragger(dragLayer);
+        grid.setLauncher(this);
+
+        workspace.setOnLongClickListener(this);
+        workspace.setDragger(dragLayer);
+        workspace.setLauncher(this);
+        loadWallpaper();
+
+        deleteZone.setLauncher(this);
+        deleteZone.setDragController(dragLayer);
+        deleteZone.setHandle(handleIcon);
+
+        dragLayer.setIgnoredDropTarget(grid);
+        dragLayer.setDragScoller(workspace);
+        dragLayer.setDragListener(deleteZone);
+    }
+
+    /**
+     * Creates a view representing a shortcut.
+     *
+     * @param info The data structure describing the shortcut.
+     *
+     * @return A View inflated from R.layout.application.
+     */
+    View createShortcut(ApplicationInfo info) {
+        return createShortcut(R.layout.application,
+                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), info);
+    }
+
+    /**
+     * Creates a view representing a shortcut inflated from the specified resource.
+     *
+     * @param layoutResId The id of the XML layout used to create the shortcut.
+     * @param parent The group the shortcut belongs to.
+     * @param info The data structure describing the shortcut.
+     *
+     * @return A View inflated from layoutResId.
+     */
+    View createShortcut(int layoutResId, ViewGroup parent, ApplicationInfo info) {
+        TextView favorite = (TextView) mInflater.inflate(layoutResId, parent, false);
+
+        if (!info.filtered) {
+            info.icon = Utilities.createIconThumbnail(info.icon, this);
+            info.filtered = true;
+        }
+
+        favorite.setCompoundDrawablesWithIntrinsicBounds(null, info.icon, null, null);
+        favorite.setText(info.title);
+        favorite.setTag(info);
+        favorite.setOnClickListener(this);
+
+        return favorite;
+    }
+
+    /**
+     * Add an application shortcut to the workspace.
+     *
+     * @param data The intent describing the application.
+     * @param cellInfo The position on screen where to create the shortcut.
+     */
+    void completeAddApplication(Context context, Intent data, CellLayout.CellInfo cellInfo,
+            boolean insertAtFirst) {
+        cellInfo.screen = mWorkspace.getCurrentScreen();
+        if (!findSingleSlot(cellInfo)) return;
+
+        // Find details for this application
+        ComponentName component = data.getComponent();
+        PackageManager packageManager = context.getPackageManager();
+        ActivityInfo activityInfo = null;
+        try {
+            activityInfo = packageManager.getActivityInfo(component, 0 /* no flags */);
+        } catch (NameNotFoundException e) {
+            Log.e(LOG_TAG, "Couldn't find ActivityInfo for selected application", e);
+        }
+        
+        if (activityInfo != null) {
+            ApplicationInfo itemInfo = new ApplicationInfo();
+            
+            itemInfo.title = activityInfo.loadLabel(packageManager);
+            if (itemInfo.title == null) {
+                itemInfo.title = activityInfo.name;
+            }
+            
+            itemInfo.setActivity(component, Intent.FLAG_ACTIVITY_NEW_TASK |
+                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+            itemInfo.icon = activityInfo.loadIcon(packageManager);
+            itemInfo.container = ItemInfo.NO_ID;
+
+            mWorkspace.addApplicationShortcut(itemInfo, cellInfo, insertAtFirst);
+        }
+    }
+    
+    /**
+     * Add a shortcut to the workspace.
+     *
+     * @param data The intent describing the shortcut.
+     * @param cellInfo The position on screen where to create the shortcut.
+     * @param insertAtFirst
+     */
+    private void completeAddShortcut(Intent data, CellLayout.CellInfo cellInfo,
+            boolean insertAtFirst) {
+        cellInfo.screen = mWorkspace.getCurrentScreen();
+        if (!findSingleSlot(cellInfo)) return;
+        
+        final ApplicationInfo info = addShortcut(this, data, cellInfo, false);
+
+        if (!mRestoring) {
+            sModel.addDesktopItem(info);
+
+            final View view = createShortcut(info);
+            mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1, insertAtFirst);
+        } else if (sModel.isDesktopLoaded()) {
+            sModel.addDesktopItem(info);
+        }
+    }
+
+    
+    /**
+     * Add a gadget to the workspace.
+     *
+     * @param data The intent describing the gadgetId.
+     * @param cellInfo The position on screen where to create the shortcut.
+     * @param insertAtFirst
+     */
+    private void completeAddGadget(Intent data, CellLayout.CellInfo cellInfo,
+            boolean insertAtFirst) {
+
+        Bundle extras = data.getExtras();
+        int gadgetId = extras.getInt(GadgetManager.EXTRA_GADGET_ID, -1);
+        
+        Log.d(LOG_TAG, "dumping extras content="+extras.toString());
+        
+        GadgetProviderInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId);
+        
+        // Calculate the grid spans needed to fit this gadget
+        CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
+        int[] spans = layout.rectToCell(gadgetInfo.minWidth, gadgetInfo.minHeight);
+        
+        // Try finding open space on Launcher screen
+        final int[] xy = mCellCoordinates;
+        if (!findSlot(cellInfo, xy, spans[0], spans[1])) return;
+
+        // Build Launcher-specific Gadget info and save to database
+        LauncherGadgetInfo launcherInfo = new LauncherGadgetInfo(gadgetId);
+        launcherInfo.spanX = spans[0];
+        launcherInfo.spanY = spans[1];
+        
+        LauncherModel.addItemToDatabase(this, launcherInfo,
+                LauncherSettings.Favorites.CONTAINER_DESKTOP,
+                mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
+
+        if (!mRestoring) {
+            sModel.addDesktopGadget(launcherInfo);
+            
+            // Perform actual inflation because we're live
+            launcherInfo.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo);
+            
+            launcherInfo.hostView.setGadget(gadgetId, gadgetInfo);
+            launcherInfo.hostView.setTag(launcherInfo);
+            
+            mWorkspace.addInCurrentScreen(launcherInfo.hostView, xy[0], xy[1],
+                    launcherInfo.spanX, launcherInfo.spanY, insertAtFirst);
+        } else if (sModel.isDesktopLoaded()) {
+            sModel.addDesktopGadget(launcherInfo);
+        }
+    }
+    
+    public LauncherGadgetHost getGadgetHost() {
+        return mGadgetHost;
+    }
+    
+    static ApplicationInfo addShortcut(Context context, Intent data,
+            CellLayout.CellInfo cellInfo, boolean notify) {
+
+        Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+        String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+        Bitmap bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
+
+        Drawable icon = null;
+        boolean filtered = false;
+        boolean customIcon = false;
+        Intent.ShortcutIconResource iconResource = null;
+
+        if (bitmap != null) {
+            icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, context));
+            filtered = true;
+            customIcon = true;
+        } else {
+            Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+            if (extra != null && extra instanceof Intent.ShortcutIconResource) {
+                try {
+                    iconResource = (Intent.ShortcutIconResource) extra;
+                    final PackageManager packageManager = context.getPackageManager();
+                    Resources resources = packageManager.getResourcesForApplication(
+                            iconResource.packageName);
+                    final int id = resources.getIdentifier(iconResource.resourceName, null, null);
+                    icon = resources.getDrawable(id);
+                } catch (Exception e) {
+                    Log.w(LOG_TAG, "Could not load shortcut icon: " + extra);
+                }
+            }
+        }
+
+        if (icon == null) {
+            icon = context.getPackageManager().getDefaultActivityIcon();
+        }
+
+        final ApplicationInfo info = new ApplicationInfo();
+        info.icon = icon;
+        info.filtered = filtered;
+        info.title = name;
+        info.intent = intent;
+        info.customIcon = customIcon;
+        info.iconResource = iconResource;
+
+        LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
+                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
+        return info;
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+
+        // Close the menu
+        if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+            getWindow().closeAllPanels();
+
+            try {
+                dismissDialog(DIALOG_CREATE_SHORTCUT);
+                // Unlock the workspace if the dialog was showing
+                mWorkspace.unlock();
+            } catch (Exception e) {
+                // An exception is thrown if the dialog is not visible, which is fine
+            }
+
+            try {
+                dismissDialog(DIALOG_RENAME_FOLDER);
+                // Unlock the workspace if the dialog was showing
+                mWorkspace.unlock();
+            } catch (Exception e) {
+                // An exception is thrown if the dialog is not visible, which is fine
+            }
+
+            // If we are already in front we go back to the default screen,
+            // otherwise we don't
+            if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) !=
+                    Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) {
+                if (!mWorkspace.isDefaultScreenShowing()) {
+                    mWorkspace.moveToDefaultScreen();
+                }
+                closeDrawer();
+                View v = getWindow().peekDecorView();
+                if (v != null && v.getWindowToken() != null) {
+                    InputMethodManager imm = (InputMethodManager)getSystemService(
+                            INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+                }
+            } else {
+                closeDrawer(false);
+            }
+        }
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        // Do not call super here
+        mSavedInstanceState = savedInstanceState;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getCurrentScreen());
+
+        final ArrayList<Folder> folders = mWorkspace.getOpenFolders();
+        if (folders.size() > 0) {
+            final int count = folders.size();
+            long[] ids = new long[count];
+            for (int i = 0; i < count; i++) {
+                final FolderInfo info = folders.get(i).getInfo();
+                ids[i] = info.id;
+            }
+            outState.putLongArray(RUNTIME_STATE_USER_FOLDERS, ids);
+        } else {
+            super.onSaveInstanceState(outState);
+        }
+
+        if (mDrawer.isOpened()) {
+            outState.putBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, true);
+        }        
+
+        if (mAddItemCellInfo != null && mAddItemCellInfo.valid && mWaitingForResult) {
+            final CellLayout.CellInfo addItemCellInfo = mAddItemCellInfo;
+            final CellLayout layout = (CellLayout) mWorkspace.getChildAt(addItemCellInfo.screen);
+
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, addItemCellInfo.screen);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, addItemCellInfo.cellX);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, addItemCellInfo.cellY);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, addItemCellInfo.spanX);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, addItemCellInfo.spanY);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_COUNT_X, layout.getCountX());
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_COUNT_Y, layout.getCountY());
+            outState.putBooleanArray(RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS,
+                   layout.getOccupiedCells());
+        }
+
+        if (mFolderInfo != null && mWaitingForResult) {
+            outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);
+            outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        mDestroyed = true;
+
+        super.onDestroy();
+        
+        try {
+            mGadgetHost.stopListening();
+        } catch (NullPointerException ex) {
+            Log.w(LOG_TAG, "problem while stopping GadgetHost during Launcher destruction", ex);
+        }
+
+        TextKeyListener.getInstance().release();
+
+        mAllAppsGrid.clearTextFilter();
+        mAllAppsGrid.setAdapter(null);
+        sModel.unbind();
+        sModel.abortLoaders();
+
+        getContentResolver().unregisterContentObserver(mObserver);
+        unregisterReceiver(mApplicationsReceiver);
+    }
+
+    @Override
+    public void startActivityForResult(Intent intent, int requestCode) {
+        mWaitingForResult = true;
+        super.startActivityForResult(intent, requestCode);
+    }
+
+    @Override
+    public void startSearch(String initialQuery, boolean selectInitialQuery, 
+            Bundle appSearchData, boolean globalSearch) {
+        if (appSearchData == null) {
+            appSearchData = new Bundle();
+            appSearchData.putString(SearchManager.SOURCE, "launcher-search");
+        }
+        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        if (mDesktopLocked) return false;
+
+        super.onCreateOptionsMenu(menu);
+        menu.add(MENU_GROUP_ADD, MENU_ADD, 0, R.string.menu_add)
+                .setIcon(android.R.drawable.ic_menu_add)
+                .setAlphabeticShortcut('A');
+        menu.add(0, MENU_WALLPAPER_SETTINGS, 0, R.string.menu_wallpaper)
+                 .setIcon(android.R.drawable.ic_menu_gallery)
+                 .setAlphabeticShortcut('W');
+        menu.add(0, MENU_SEARCH, 0, R.string.menu_search)
+                .setIcon(android.R.drawable.ic_search_category_default)
+                .setAlphabeticShortcut(SearchManager.MENU_KEY);
+        menu.add(0, MENU_NOTIFICATIONS, 0, R.string.menu_notifications)
+                .setIcon(com.android.internal.R.drawable.ic_menu_notifications)
+                .setAlphabeticShortcut('N');
+
+        final Intent settings = new Intent(android.provider.Settings.ACTION_SETTINGS);
+        settings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+        menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings)
+                .setIcon(android.R.drawable.ic_menu_preferences).setAlphabeticShortcut('P')
+                .setIntent(settings);
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+
+        mMenuAddInfo = mWorkspace.findAllVacantCells(null);
+        menu.setGroupEnabled(MENU_GROUP_ADD, mMenuAddInfo != null && mMenuAddInfo.valid);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ADD:
+                addItems();
+                return true;
+            case MENU_WALLPAPER_SETTINGS:
+                startWallpaper();
+                return true;
+            case MENU_SEARCH:
+                if (mWorkspace.snapToSearch()) {
+                    closeDrawer(true);          // search gadget: get drawer out of the way
+                } else {
+                    onSearchRequested();        // no search gadget: use system search UI
+                }
+                return true;
+            case MENU_NOTIFICATIONS:
+                showNotifications();
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void addItems() {
+        showAddDialog(mMenuAddInfo);
+    }
+
+    private void removeShortcutsForPackage(String packageName) {
+        if (packageName != null && packageName.length() > 0) {
+            mWorkspace.removeShortcutsForPackage(packageName);
+        }
+    }
+    
+    void addGadget(Intent data) {
+        // TODO: catch bad gadget exception when sent
+        int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1);
+        GadgetProviderInfo gadget = mGadgetManager.getGadgetInfo(gadgetId);
+
+        if (gadget.configure != null) {
+            // Launch over to configure gadget, if needed
+            Intent intent = new Intent(GadgetManager.ACTION_GADGET_CONFIGURE);
+            intent.setComponent(gadget.configure);
+            intent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
+
+            startActivityForResult(intent, REQUEST_CREATE_GADGET);
+        } else {
+            // Otherwise just add it
+            onActivityResult(REQUEST_CREATE_GADGET, Activity.RESULT_OK, data);
+        }
+    }
+    
+    void addSearch() {
+        final Widget info = Widget.makeSearch();
+        final CellLayout.CellInfo cellInfo = mAddItemCellInfo;
+        
+        final int[] xy = mCellCoordinates;
+        final int spanX = info.spanX;
+        final int spanY = info.spanY;
+    
+        if (!findSlot(cellInfo, xy, spanX, spanY)) return;
+    
+        sModel.addDesktopItem(info);
+        LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
+        mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
+    
+        final View view = mInflater.inflate(info.layoutResource, null);
+        view.setTag(info);
+    
+        mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY);
+    }
+
+    void addShortcut(Intent intent) {
+        startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
+    }
+
+    void addLiveFolder(Intent intent) {
+        startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
+    }
+
+    void addFolder(boolean insertAtFirst) {
+        UserFolderInfo folderInfo = new UserFolderInfo();
+        folderInfo.title = getText(R.string.folder_name);
+
+        CellLayout.CellInfo cellInfo = mAddItemCellInfo;
+        cellInfo.screen = mWorkspace.getCurrentScreen();
+        if (!findSingleSlot(cellInfo)) return;
+
+        // Update the model
+        LauncherModel.addItemToDatabase(this, folderInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
+                mWorkspace.getCurrentScreen(), cellInfo.cellX, cellInfo.cellY, false);
+        sModel.addDesktopItem(folderInfo);
+        sModel.addFolder(folderInfo);
+
+        // Create the view
+        FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
+                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), folderInfo);
+        mWorkspace.addInCurrentScreen(newFolder,
+                cellInfo.cellX, cellInfo.cellY, 1, 1, insertAtFirst);
+    }
+    
+    private void completeAddLiveFolder(Intent data, CellLayout.CellInfo cellInfo,
+            boolean insertAtFirst) {
+        cellInfo.screen = mWorkspace.getCurrentScreen();
+        if (!findSingleSlot(cellInfo)) return;
+
+        final LiveFolderInfo info = addLiveFolder(this, data, cellInfo, false);
+
+        if (!mRestoring) {
+            sModel.addDesktopItem(info);
+
+            final View view = LiveFolderIcon.fromXml(R.layout.live_folder_icon, this,
+                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), info);
+            mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1, insertAtFirst);
+        } else if (sModel.isDesktopLoaded()) {
+            sModel.addDesktopItem(info);
+        }
+    }
+
+    static LiveFolderInfo addLiveFolder(Context context, Intent data,
+            CellLayout.CellInfo cellInfo, boolean notify) {
+
+        Intent baseIntent = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT);
+        String name = data.getStringExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME);
+
+        Drawable icon = null;
+        boolean filtered = false;
+        Intent.ShortcutIconResource iconResource = null;
+
+        Parcelable extra = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON);
+        if (extra != null && extra instanceof Intent.ShortcutIconResource) {
+            try {
+                iconResource = (Intent.ShortcutIconResource) extra;
+                final PackageManager packageManager = context.getPackageManager();
+                Resources resources = packageManager.getResourcesForApplication(
+                        iconResource.packageName);
+                final int id = resources.getIdentifier(iconResource.resourceName, null, null);
+                icon = resources.getDrawable(id);
+            } catch (Exception e) {
+                Log.w(LOG_TAG, "Could not load live folder icon: " + extra);
+            }
+        }
+
+        if (icon == null) {
+            icon = context.getResources().getDrawable(R.drawable.ic_launcher_folder);
+        }
+
+        final LiveFolderInfo info = new LiveFolderInfo();
+        info.icon = icon;
+        info.filtered = filtered;
+        info.title = name;
+        info.iconResource = iconResource;
+        info.uri = data.getData();
+        info.baseIntent = baseIntent;
+        info.displayMode = data.getIntExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
+                LiveFolders.DISPLAY_MODE_GRID);
+
+        LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
+                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
+        sModel.addFolder(info);
+
+        return info;
+    }
+
+    private boolean findSingleSlot(CellLayout.CellInfo cellInfo) {
+        final int[] xy = new int[2];
+        if (findSlot(cellInfo, xy, 1, 1)) {
+            cellInfo.cellX = xy[0];
+            cellInfo.cellY = xy[1];
+            return true;
+        }
+        return false;
+    }
+
+    private boolean findSlot(CellLayout.CellInfo cellInfo, int[] xy, int spanX, int spanY) {
+        if (!cellInfo.findCellForSpan(xy, spanX, spanY)) {
+            boolean[] occupied = mSavedState != null ?
+                    mSavedState.getBooleanArray(RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS) : null;
+            cellInfo = mWorkspace.findAllVacantCells(occupied);
+            if (!cellInfo.findCellForSpan(xy, spanX, spanY)) {
+                Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void showNotifications() {
+        final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);
+        if (statusBar != null) {
+            statusBar.expand();
+        }
+    }
+
+    private void startWallpaper() {
+        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
+        startActivity(Intent.createChooser(pickWallpaper, getString(R.string.chooser_wallpaper)));
+    }
+
+    /**
+     * Registers various intent receivers. The current implementation registers
+     * only a wallpaper intent receiver to let other applications change the
+     * wallpaper.
+     */
+    private void registerIntentReceivers() {
+        if (sWallpaperReceiver == null) {
+            final Application application = getApplication();
+
+            sWallpaperReceiver = new WallpaperIntentReceiver(application, this);
+
+            IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+            application.registerReceiver(sWallpaperReceiver, filter);
+        } else {
+            sWallpaperReceiver.setLauncher(this);
+        }
+
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        registerReceiver(mApplicationsReceiver, filter);
+    }
+
+    /**
+     * Registers various content observers. The current implementation registers
+     * only a favorites observer to keep track of the favorites applications.
+     */
+    private void registerContentObservers() {
+        ContentResolver resolver = getContentResolver();
+        resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (event.getKeyCode()) {
+                case KeyEvent.KEYCODE_BACK:
+                    mWorkspace.dispatchKeyEvent(event); 
+                    closeFolder();
+                    closeDrawer();
+                    return true;
+                case KeyEvent.KEYCODE_HOME:
+                    return true;
+            }
+        }
+
+        return super.dispatchKeyEvent(event);
+    }
+
+    private void closeDrawer() {
+        closeDrawer(true);
+    }
+
+    private void closeDrawer(boolean animated) {
+        if (mDrawer.isOpened()) {
+            if (animated) {
+                mDrawer.animateClose();
+            } else {
+                mDrawer.close();
+            }
+            if (mDrawer.hasFocus()) {
+                mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
+            }
+        }
+    }
+
+    private void closeFolder() {
+        Folder folder = mWorkspace.getOpenFolder();
+        if (folder != null) {
+            closeFolder(folder);
+        }
+    }
+
+    void closeFolder(Folder folder) {
+        folder.getInfo().opened = false;
+        ViewGroup parent = (ViewGroup) folder.getParent();
+        if (parent != null) {
+            parent.removeView(folder);
+        }
+        folder.onClose();
+    }
+
+    /**
+     * When the notification that favorites have changed is received, requests
+     * a favorites list refresh.
+     */
+    private void onFavoritesChanged() {
+        mDesktopLocked = true;
+        mDrawer.lock();
+        sModel.loadUserItems(false, this, false, false);
+    }
+
+    void onDesktopItemsLoaded() {
+        if (mDestroyed) return;
+
+        mAllAppsGrid.setAdapter(Launcher.getModel().getApplicationsAdapter());
+        bindDesktopItems();
+    }
+
+    /**
+     * Refreshes the shortcuts shown on the workspace.
+     */
+    private void bindDesktopItems() {
+        final ArrayList<ItemInfo> shortcuts = sModel.getDesktopItems();
+        final ArrayList<LauncherGadgetInfo> gadgets = sModel.getDesktopGadgets();
+        if (shortcuts == null || gadgets == null) {
+            return;
+        }
+
+        final Workspace workspace = mWorkspace;
+        int count = workspace.getChildCount();
+        for (int i = 0; i < count; i++) {
+            ((ViewGroup) workspace.getChildAt(i)).removeAllViewsInLayout();
+        }
+        
+        if (DEBUG_USER_INTERFACE) {
+            android.widget.Button finishButton = new android.widget.Button(this);
+            finishButton.setText("Finish");
+            workspace.addInScreen(finishButton, 1, 0, 0, 1, 1);
+
+            finishButton.setOnClickListener(new android.widget.Button.OnClickListener() {
+                public void onClick(View v) {
+                    finish();
+                }
+            });
+        }
+
+        final DesktopBinder binder = new DesktopBinder(this, shortcuts, gadgets);
+        binder.startBindingItems();
+    }
+
+    private void bindItems(Launcher.DesktopBinder binder,
+            ArrayList<ItemInfo> shortcuts, int start, int count) {
+
+        final Workspace workspace = mWorkspace;
+        final boolean desktopLocked = mDesktopLocked;
+
+        final int end = Math.min(start + DesktopBinder.ITEMS_COUNT, count);
+        int i = start;
+
+        for ( ; i < end; i++) {
+            final ItemInfo item = shortcuts.get(i);
+            switch (item.itemType) {
+                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                    final View shortcut = createShortcut((ApplicationInfo) item);
+                    workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
+                            !desktopLocked);
+                    break;
+                case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+                    final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
+                            (ViewGroup) workspace.getChildAt(workspace.getCurrentScreen()),
+                            (UserFolderInfo) item);
+                    workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
+                            !desktopLocked);
+                    break;
+                case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
+                    final FolderIcon newLiveFolder = LiveFolderIcon.fromXml(
+                            R.layout.live_folder_icon, this,
+                            (ViewGroup) workspace.getChildAt(workspace.getCurrentScreen()),
+                            (LiveFolderInfo) item);
+                    workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1,
+                            !desktopLocked);
+                    break;
+                case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
+                    final int screen = workspace.getCurrentScreen();
+                    final View view = mInflater.inflate(R.layout.widget_search,
+                            (ViewGroup) workspace.getChildAt(screen), false);
+                    
+                    final Widget widget = (Widget) item;
+                    view.setTag(widget);
+                    
+                    workspace.addWidget(view, widget, !desktopLocked);
+                    break;
+            }
+        }
+
+        workspace.requestLayout();
+
+        if (end >= count) {
+            finishBindDesktopItems();
+            binder.startBindingGadgets();
+        } else {
+            binder.obtainMessage(DesktopBinder.MESSAGE_BIND_ITEMS, i, count).sendToTarget();
+        }
+    }
+
+    private void finishBindDesktopItems() {
+        if (mSavedState != null) {
+            if (!mWorkspace.hasFocus()) {
+                mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
+            }
+
+            final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);
+            if (userFolders != null) {
+                for (long folderId : userFolders) {
+                    final FolderInfo info = sModel.findFolderById(folderId);
+                    if (info != null) {
+                        openFolder(info);
+                    }
+                }
+                final Folder openFolder = mWorkspace.getOpenFolder();
+                if (openFolder != null) {
+                    openFolder.requestFocus();
+                }
+            }
+
+            final boolean allApps = mSavedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
+            if (allApps) {
+                mDrawer.open();
+            }
+
+            mSavedState = null;
+        }
+
+        if (mSavedInstanceState != null) {
+            super.onRestoreInstanceState(mSavedInstanceState);
+            mSavedInstanceState = null;
+        }
+
+        if (mDrawer.isOpened() && !mDrawer.hasFocus()) {
+            mDrawer.requestFocus();
+        }
+
+        mDesktopLocked = false;
+        mDrawer.unlock();
+    }
+
+    private void bindGadgets(Launcher.DesktopBinder binder,
+            ArrayList<LauncherGadgetInfo> gadgets, int start, int count) {
+
+        final Workspace workspace = mWorkspace;
+        final boolean desktopLocked = mDesktopLocked;
+
+        final int end = Math.min(start + DesktopBinder.GADGETS_COUNT, count);
+        int i = start;
+
+        for ( ; i < end; i++) {
+            final LauncherGadgetInfo item = gadgets.get(i);
+                    
+            final int gadgetId = item.gadgetId;
+            final GadgetProviderInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId);
+            item.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo);
+            
+            if (LOGD) Log.d(LOG_TAG, String.format("about to setGadget for id=%d, info=%s", gadgetId, gadgetInfo));
+            
+            item.hostView.setGadget(gadgetId, gadgetInfo);
+            item.hostView.setTag(item);
+            
+            workspace.addInScreen(item.hostView, item.screen, item.cellX,
+                    item.cellY, item.spanX, item.spanY, !desktopLocked);
+        }
+
+        workspace.requestLayout();
+
+        if (end >= count) {
+            finishBindDesktopGadgets();
+        } else {
+            binder.obtainMessage(DesktopBinder.MESSAGE_BIND_GADGETS, i, count).sendToTarget();
+        }
+    }
+    
+    private void finishBindDesktopGadgets() {
+    }
+    
+    DragController getDragController() {
+        return mDragLayer;
+    }
+
+    /**
+     * Launches the intent referred by the clicked shortcut.
+     *
+     * @param v The view representing the clicked shortcut.
+     */
+    public void onClick(View v) {
+        Object tag = v.getTag();
+        if (tag instanceof ApplicationInfo) {
+            // Open shortcut
+            final Intent intent = ((ApplicationInfo) tag).intent;
+            startActivitySafely(intent);
+        } else if (tag instanceof FolderInfo) {
+            handleFolderClick((FolderInfo) tag);
+        }
+    }
+
+    void startActivitySafely(Intent intent) {
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+        } catch (SecurityException e) {
+            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+            Log.e(LOG_TAG, "Launcher does not have the permission to launch " + intent +
+                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
+                    "or use the exported attribute for this activity.", e);
+        }
+    }
+
+    private void handleFolderClick(FolderInfo folderInfo) {
+        if (!folderInfo.opened) {
+            // Close any open folder
+            closeFolder();
+            // Open the requested folder
+            openFolder(folderInfo);
+        } else {
+            // Find the open folder...
+            Folder openFolder = mWorkspace.getFolderForTag(folderInfo);
+            int folderScreen;
+            if (openFolder != null) {
+                folderScreen = mWorkspace.getScreenForView(openFolder);
+                // .. and close it
+                closeFolder(openFolder);
+                if (folderScreen != mWorkspace.getCurrentScreen()) {
+                    // Close any folder open on the current screen
+                    closeFolder();
+                    // Pull the folder onto this screen
+                    openFolder(folderInfo);
+                }
+            }
+        }
+    }
+
+    private void loadWallpaper() {
+        // The first time the application is started, we load the wallpaper from
+        // the ApplicationContext
+        if (sWallpaper == null) {
+            final Drawable drawable = getWallpaper();
+            if (drawable instanceof BitmapDrawable) {
+                sWallpaper = ((BitmapDrawable) drawable).getBitmap();
+            } else {
+                throw new IllegalStateException("The wallpaper must be a BitmapDrawable.");
+            }
+        }
+        mWorkspace.loadWallpaper(sWallpaper);
+    }
+
+    /**
+     * Opens the user fodler described by the specified tag. The opening of the folder
+     * is animated relative to the specified View. If the View is null, no animation
+     * is played.
+     *
+     * @param folderInfo The FolderInfo describing the folder to open.
+     */
+    private void openFolder(FolderInfo folderInfo) {
+        Folder openFolder;
+
+        if (folderInfo instanceof UserFolderInfo) {
+            openFolder = UserFolder.fromXml(this);
+        } else if (folderInfo instanceof LiveFolderInfo) {
+            openFolder = com.android.launcher.LiveFolder.fromXml(this, folderInfo);
+        } else {
+            return;
+        }
+
+        openFolder.setDragger(mDragLayer);
+        openFolder.setLauncher(this);
+
+        openFolder.bind(folderInfo);
+        folderInfo.opened = true;
+
+        mWorkspace.addInScreen(openFolder, folderInfo.screen, 0, 0, 4, 4);
+        openFolder.onOpen();
+    }
+
+    /**
+     * Returns true if the workspace is being loaded. When the workspace is loading,
+     * no user interaction should be allowed to avoid any conflict.
+     *
+     * @return True if the workspace is locked, false otherwise.
+     */
+    boolean isWorkspaceLocked() {
+        return mDesktopLocked;
+    }
+
+    public boolean onLongClick(View v) {
+        if (mDesktopLocked) {
+            return false;
+        }
+
+        if (!(v instanceof CellLayout)) {
+            v = (View) v.getParent();
+        }
+
+        CellLayout.CellInfo cellInfo = (CellLayout.CellInfo) v.getTag();
+
+        // This happens when long clicking an item with the dpad/trackball
+        if (cellInfo == null) {
+            return true;
+        }
+
+        if (mWorkspace.allowLongPress()) {
+            if (cellInfo.cell == null) {
+                if (cellInfo.valid) {
+                    // User long pressed on empty space
+                    showAddDialog(cellInfo);
+                }
+            } else {
+                if (!(cellInfo.cell instanceof Folder)) {
+                    // User long pressed on an item
+                    mWorkspace.startDrag(cellInfo);
+                }
+            }
+        }
+        return true;
+    }
+
+    static LauncherModel getModel() {
+        return sModel;
+    }
+
+    void closeAllApplications() {
+        mDrawer.close();
+    }
+
+    boolean isDrawerDown() {
+        return !mDrawer.isMoving() && !mDrawer.isOpened();
+    }
+
+    boolean isDrawerUp() {
+        return mDrawer.isOpened() && !mDrawer.isMoving();
+    }
+
+    Workspace getWorkspace() {
+        return mWorkspace;
+    }
+
+    GridView getApplicationsGrid() {
+        return mAllAppsGrid;
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case DIALOG_CREATE_SHORTCUT:
+                return new CreateShortcut().createDialog();
+            case DIALOG_RENAME_FOLDER:
+                return new RenameFolder().createDialog();
+        }
+
+        return super.onCreateDialog(id);
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        switch (id) {
+            case DIALOG_CREATE_SHORTCUT:
+                mWorkspace.lock();
+                break;
+            case DIALOG_RENAME_FOLDER:
+                mWorkspace.lock();
+                EditText input = (EditText) dialog.findViewById(R.id.folder_name);
+                final CharSequence text = mFolderInfo.title;
+                input.setText(text);
+                input.setSelection(0, text.length());                
+                break;
+        }
+    }
+
+    void showRenameDialog(FolderInfo info) {
+        mFolderInfo = info;
+        mWaitingForResult = true;
+        showDialog(DIALOG_RENAME_FOLDER);
+    }
+
+    private void showAddDialog(CellLayout.CellInfo cellInfo) {
+        mAddItemCellInfo = cellInfo;
+        mWaitingForResult = true;
+        showDialog(DIALOG_CREATE_SHORTCUT);
+    }
+
+    private class RenameFolder {
+        private EditText mInput;
+
+        Dialog createDialog() {
+            mWaitingForResult = true;
+            final View layout = View.inflate(Launcher.this, R.layout.rename_folder, null);
+            mInput = (EditText) layout.findViewById(R.id.folder_name);
+
+            AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
+            builder.setIcon(0);
+            builder.setTitle(getString(R.string.rename_folder_title));
+            builder.setCancelable(true);
+            builder.setOnCancelListener(new Dialog.OnCancelListener() {
+                public void onCancel(DialogInterface dialog) {
+                    cleanup();
+                }
+            });
+            builder.setNegativeButton(getString(R.string.cancel_action),
+                new Dialog.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        cleanup();
+                    }
+                }
+            );
+            builder.setPositiveButton(getString(R.string.rename_action),
+                new Dialog.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        changeFolderName();
+                    }
+                }
+            );
+            builder.setView(layout);
+            return builder.create();
+        }
+
+        private void changeFolderName() {
+            final String name = mInput.getText().toString();
+            if (!TextUtils.isEmpty(name)) {
+                // Make sure we have the right folder info
+                mFolderInfo = sModel.findFolderById(mFolderInfo.id);
+                mFolderInfo.title = name;
+                LauncherModel.updateItemInDatabase(Launcher.this, mFolderInfo);
+
+                if (mDesktopLocked) {
+                    mDrawer.lock();
+                    sModel.loadUserItems(false, Launcher.this, false, false);
+                } else {
+                    final FolderIcon folderIcon = (FolderIcon)
+                            mWorkspace.getViewForTag(mFolderInfo);
+                    if (folderIcon != null) {
+                        folderIcon.setText(name);
+                        getWorkspace().requestLayout();
+                    } else {
+                        mDesktopLocked = true;
+                        mDrawer.lock();
+                        sModel.loadUserItems(false, Launcher.this, false, false);
+                    }
+                }
+            }
+            cleanup();
+        }
+
+        private void cleanup() {
+            mWorkspace.unlock();
+            dismissDialog(DIALOG_RENAME_FOLDER);
+            mWaitingForResult = false;
+            mFolderInfo = null;
+        }
+    }
+
+    /**
+     * Displays the shortcut creation dialog and launches, if necessary, the
+     * appropriate activity.
+     */
+    private class CreateShortcut implements AdapterView.OnItemClickListener,
+            DialogInterface.OnCancelListener {
+        private AddAdapter mAdapter;
+        private ListView mList;
+        
+        Dialog createDialog() {
+            mWaitingForResult = true;
+            
+            mAdapter = new AddAdapter(Launcher.this);
+            
+            final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
+            builder.setTitle(getString(R.string.menu_item_add_item));
+            builder.setIcon(0);
+
+            mList = (ListView)
+                    View.inflate(Launcher.this, R.layout.create_shortcut_list, null);
+            mList.setAdapter(mAdapter);
+            mList.setOnItemClickListener(this);
+            builder.setView(mList);
+            builder.setInverseBackgroundForced(true);
+
+            AlertDialog dialog = builder.create();
+            dialog.setOnCancelListener(this);
+
+            WindowManager.LayoutParams attributes = dialog.getWindow().getAttributes();
+            attributes.gravity = Gravity.TOP;
+            dialog.onWindowAttributesChanged(attributes);
+
+            return dialog;
+        }
+
+        public void onCancel(DialogInterface dialog) {
+            mWaitingForResult = false;
+            cleanup();
+        }
+
+        private void cleanup() {
+            mWorkspace.unlock();
+            dismissDialog(DIALOG_CREATE_SHORTCUT);
+        }
+
+        public void onItemClick(AdapterView parent, View view, int position, long id) {
+            // handle which item was clicked based on position
+            // this will launch off pick intent
+            
+            Object tag = view.getTag();
+            if (tag instanceof AddAdapter.ListItem) {
+                AddAdapter.ListItem item = (AddAdapter.ListItem) tag;
+                cleanup();
+                switch (item.actionTag) {
+                    case AddAdapter.ITEM_APPLICATION: {
+                        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+                        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+                        pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
+                        startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
+                        break;
+                    }
+
+                    case AddAdapter.ITEM_SHORTCUT: {
+                        Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+
+                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+                        pickIntent.putExtra(Intent.EXTRA_INTENT, shortcutIntent);
+                        pickIntent.putExtra(Intent.EXTRA_TITLE,
+                                getText(R.string.title_select_shortcut));
+                        startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
+                        break;
+                    }
+                    
+                    case AddAdapter.ITEM_SEARCH: {
+                        addSearch();
+                        break;
+                    }
+                    
+                    case AddAdapter.ITEM_GADGET: {
+                        int gadgetId = Launcher.this.mGadgetHost.allocateGadgetId();
+                        
+                        Intent pickIntent = new Intent(GadgetManager.ACTION_GADGET_PICK);
+                        pickIntent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
+                        startActivityForResult(pickIntent, REQUEST_PICK_GADGET);
+                        break;
+                    }
+                    
+                    case AddAdapter.ITEM_LIVE_FOLDER: {
+                        Intent liveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
+
+                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+                        pickIntent.putExtra(Intent.EXTRA_INTENT, liveFolderIntent);
+                        pickIntent.putExtra(Intent.EXTRA_TITLE,
+                                getText(R.string.title_select_live_folder));
+                        startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
+                        break;
+                    }
+
+                    case AddAdapter.ITEM_FOLDER: {
+                        addFolder(!mDesktopLocked);
+                        dismissDialog(DIALOG_CREATE_SHORTCUT);
+                        break;
+                    }
+
+                    case AddAdapter.ITEM_WALLPAPER: {
+                        startWallpaper();
+                        break;
+                    }
+
+                }                
+                
+            }
+        }
+    }
+
+    /**
+     * Receives notifications when applications are added/removed.
+     */
+    private class ApplicationsIntentReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            boolean reloadWorkspace = false;
+            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
+                } else {
+                    reloadWorkspace = true;
+                }
+            }
+            removeDialog(DIALOG_CREATE_SHORTCUT);
+            if (!reloadWorkspace) {
+                sModel.loadApplications(false, Launcher.this, false);
+            } else {
+                sModel.loadUserItems(false, Launcher.this, false, true);
+            }
+        }
+    }
+
+    /**
+     * Receives notifications whenever the user favorites have changed.
+     */
+    private class FavoritesChangeObserver extends ContentObserver {
+        public FavoritesChangeObserver() {
+            super(new Handler());
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onFavoritesChanged();
+        }
+    }
+
+    /**
+     * Receives intents from other applications to change the wallpaper.
+     */
+    private static class WallpaperIntentReceiver extends BroadcastReceiver {
+        private final Application mApplication;
+        private WeakReference<Launcher> mLauncher;
+
+        WallpaperIntentReceiver(Application application, Launcher launcher) {
+            mApplication = application;
+            setLauncher(launcher);
+        }
+
+        void setLauncher(Launcher launcher) {
+            mLauncher = new WeakReference<Launcher>(launcher);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Load the wallpaper from the ApplicationContext and store it locally
+            // until the Launcher Activity is ready to use it
+            final Drawable drawable = mApplication.getWallpaper();
+            if (drawable instanceof BitmapDrawable) {
+                sWallpaper = ((BitmapDrawable) drawable).getBitmap();
+            } else {
+                throw new IllegalStateException("The wallpaper must be a BitmapDrawable.");
+            }
+
+            // If Launcher is alive, notify we have a new wallpaper
+            if (mLauncher != null) {
+                final Launcher launcher = mLauncher.get();
+                if (launcher != null) {
+                    launcher.loadWallpaper();
+                }
+            }
+        }
+    }
+
+    private class DrawerManager implements SlidingDrawer.OnDrawerOpenListener,
+            SlidingDrawer.OnDrawerCloseListener, SlidingDrawer.OnDrawerScrollListener {
+        private boolean mOpen;
+
+        public void onDrawerOpened() {
+            if (!mOpen) {
+                mHandleIcon.reverseTransition(150);
+                final Rect bounds = mWorkspace.mDrawerBounds;
+
+                View view = mAllAppsGrid;
+                view.getDrawingRect(bounds);
+
+                while (view != mDragLayer) {
+                    bounds.offset(view.getLeft(), view.getTop());
+                    view = (View) view.getParent();
+                }
+
+                mOpen = true;
+            }
+        }
+
+        public void onDrawerClosed() {
+            if (mOpen) {
+                mHandleIcon.reverseTransition(150);
+                mWorkspace.mDrawerBounds.setEmpty();
+                mOpen = false;
+            }
+            mAllAppsGrid.setSelection(0);
+            mAllAppsGrid.clearTextFilter();
+        }
+
+        public void onScrollStarted() {
+        }
+
+        public void onScrollEnded() {
+        }
+    }
+
+    private static class DesktopBinder extends Handler {
+        static final int MESSAGE_BIND_ITEMS = 0x1;
+        static final int MESSAGE_BIND_GADGETS = 0x2;
+        // Number of items to bind in every pass
+        static final int ITEMS_COUNT = 6;
+        static final int GADGETS_COUNT = 1;
+
+        private final ArrayList<ItemInfo> mShortcuts;
+        private final ArrayList<LauncherGadgetInfo> mGadgets;
+        private final WeakReference<Launcher> mLauncher;
+
+        DesktopBinder(Launcher launcher, ArrayList<ItemInfo> shortcuts,
+                ArrayList<LauncherGadgetInfo> gadgets) {
+
+            mLauncher = new WeakReference<Launcher>(launcher);
+            mShortcuts = shortcuts;
+            mGadgets = gadgets;
+        }
+        
+        public void startBindingItems() {
+            obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts.size()).sendToTarget();
+        }
+
+        public void startBindingGadgets() {
+            obtainMessage(MESSAGE_BIND_GADGETS, 0, mGadgets.size()).sendToTarget();
+        }
+        
+        @Override
+        public void handleMessage(Message msg) {
+            Launcher launcher = mLauncher.get();
+            if (launcher == null) {
+                return;
+            }
+            
+            switch (msg.what) {
+                case MESSAGE_BIND_ITEMS: {
+                    launcher.bindItems(this, mShortcuts, msg.arg1, msg.arg2);
+                    break;
+                }
+                case MESSAGE_BIND_GADGETS: {
+                    launcher.bindGadgets(this, mGadgets, msg.arg1, msg.arg2);
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher/LauncherApplication.java b/src/com/android/launcher/LauncherApplication.java
new file mode 100644
index 0000000..d71fa19
--- /dev/null
+++ b/src/com/android/launcher/LauncherApplication.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.app.Application;
+import dalvik.system.VMRuntime;
+
+public class LauncherApplication extends Application {
+    @Override
+    public void onCreate() {
+        VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
+
+        super.onCreate();
+    }
+}
diff --git a/src/com/android/launcher/LauncherGadgetHost.java b/src/com/android/launcher/LauncherGadgetHost.java
new file mode 100644
index 0000000..9bb4f05
--- /dev/null
+++ b/src/com/android/launcher/LauncherGadgetHost.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 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.launcher;
+
+import android.content.Context;
+import android.gadget.GadgetHost;
+import android.gadget.GadgetHostView;
+import android.gadget.GadgetProviderInfo;
+
+/**
+ * Specific {@link GadgetHost} that creates our {@link LauncherGadgetHostView}
+ * which correctly captures all long-press events. This ensures that users can
+ * always pick up and move gadgets.
+ */
+public class LauncherGadgetHost extends GadgetHost {
+    public LauncherGadgetHost(Context context, int hostId) {
+        super(context, hostId);
+    }
+    
+    protected GadgetHostView onCreateView(Context context, int gadgetId,
+            GadgetProviderInfo gadget) {
+        return new LauncherGadgetHostView(context);
+    }
+}
diff --git a/src/com/android/launcher/LauncherGadgetHostView.java b/src/com/android/launcher/LauncherGadgetHostView.java
new file mode 100644
index 0000000..2b5f7f7
--- /dev/null
+++ b/src/com/android/launcher/LauncherGadgetHostView.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 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.launcher;
+
+import android.content.Context;
+import android.gadget.GadgetHostView;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+/**
+ * {@inheritDoc}
+ */
+public class LauncherGadgetHostView extends GadgetHostView {
+    private boolean mHasPerformedLongPress;
+    
+    private CheckForLongPress mPendingCheckForLongPress;
+    
+    private LayoutInflater mInflater;
+    
+    public LauncherGadgetHostView(Context context) {
+        super(context);
+        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+    
+    @Override
+    protected View getErrorView() {
+        return mInflater.inflate(R.layout.gadget_error, this, false);
+    }
+
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        // Consume any touch events for ourselves after longpress is triggered
+        if (mHasPerformedLongPress) {
+            mHasPerformedLongPress = false;
+            return true;
+        }
+            
+        // Watch for longpress events at this level to make sure
+        // users can always pick up this Gadget
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                postCheckForLongClick();
+                break;
+            }
+            
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mHasPerformedLongPress = false;
+                if (mPendingCheckForLongPress != null) {
+                    removeCallbacks(mPendingCheckForLongPress);
+                }
+                break;
+        }
+        
+        // Otherwise continue letting touch events fall through to children
+        return false;
+    }
+    
+    class CheckForLongPress implements Runnable {
+        private int mOriginalWindowAttachCount;
+
+        public void run() {
+            if ((mParent != null) && hasWindowFocus()
+                    && mOriginalWindowAttachCount == getWindowAttachCount()
+                    && !mHasPerformedLongPress) {
+                if (performLongClick()) {
+                    mHasPerformedLongPress = true;
+                }
+            }
+        }
+
+        public void rememberWindowAttachCount() {
+            mOriginalWindowAttachCount = getWindowAttachCount();
+        }
+    }
+
+    private void postCheckForLongClick() {
+        mHasPerformedLongPress = false;
+
+        if (mPendingCheckForLongPress == null) {
+            mPendingCheckForLongPress = new CheckForLongPress();
+        }
+        mPendingCheckForLongPress.rememberWindowAttachCount();
+        postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());
+    }
+}
diff --git a/src/com/android/launcher/LauncherGadgetInfo.java b/src/com/android/launcher/LauncherGadgetInfo.java
new file mode 100644
index 0000000..65fa774
--- /dev/null
+++ b/src/com/android/launcher/LauncherGadgetInfo.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 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.launcher;
+
+import android.content.ContentValues;
+import android.gadget.GadgetHostView;
+
+/**
+ * Represents a gadget, which just contains an identifier.
+ */
+class LauncherGadgetInfo extends ItemInfo {
+
+    /**
+     * Identifier for this gadget when talking with {@link GadgetManager} for updates.
+     */
+    int gadgetId;
+    
+    /**
+     * View that holds this gadget after it's been created.  This view isn't created
+     * until Launcher knows it's needed.
+     */
+    GadgetHostView hostView = null;
+
+    LauncherGadgetInfo(int gadgetId) {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_GADGET;
+        this.gadgetId = gadgetId;
+    }
+    
+    @Override
+    void onAddToDatabase(ContentValues values) {
+        super.onAddToDatabase(values);
+        values.put(LauncherSettings.Favorites.GADGET_ID, gadgetId);
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toString(gadgetId);
+    }
+}
diff --git a/src/com/android/launcher/LauncherModel.java b/src/com/android/launcher/LauncherModel.java
new file mode 100644
index 0000000..40b5402
--- /dev/null
+++ b/src/com/android/launcher/LauncherModel.java
@@ -0,0 +1,995 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.util.Log;
+import android.os.Process;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Comparator;
+import java.lang.ref.WeakReference;
+import java.text.Collator;
+import java.net.URISyntaxException;
+
+/**
+ * Maintains in-memory state of the Launcher. It is expected that there should be only one
+ * LauncherModel object held in a static. Also provide APIs for updating the database state
+ * for the Launcher
+ */
+public class LauncherModel {
+    private static final int UI_NOTIFICATION_RATE = 4;
+    private static final int DEFAULT_APPLICATIONS_NUMBER = 42;
+    private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000;
+
+    private final Collator sCollator = Collator.getInstance();    
+
+    private boolean mApplicationsLoaded;
+    private boolean mDesktopItemsLoaded;
+
+    private ArrayList<ItemInfo> mDesktopItems;
+    private ArrayList<LauncherGadgetInfo> mDesktopGadgets;
+    private HashMap<Long, FolderInfo> mFolders;
+
+    private ArrayList<ApplicationInfo> mApplications;
+    private ApplicationsAdapter mApplicationsAdapter;
+    private ApplicationsLoader mApplicationsLoader;
+    private DesktopItemsLoader mDesktopItemsLoader;
+    private Thread mLoader;
+    private Thread mDesktopLoader;
+
+    void abortLoaders() {
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            mApplicationsLoader.stop();
+            mApplicationsLoaded = false;
+        }
+        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
+            mDesktopItemsLoader.stop();
+            mDesktopItemsLoaded = false;
+        }
+    }
+
+    /**
+     * Loads the list of installed applications in mApplications.
+     */
+    void loadApplications(boolean isLaunching, Launcher launcher, boolean localeChanged) {
+        if (isLaunching && mApplicationsLoaded && !localeChanged) {
+            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
+            return;
+        }
+
+        if (mApplicationsAdapter == null || isLaunching || localeChanged) {
+            mApplicationsAdapter = new ApplicationsAdapter(launcher,
+                    mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER));
+        }
+
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            mApplicationsLoader.stop();
+            // Wait for the currently running thread to finish, this can take a little
+            // time but it should be well below the timeout limit
+            try {
+                mLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
+            } catch (InterruptedException e) {
+                // Empty
+            }
+        }
+
+        mApplicationsLoaded = false;
+
+        if (!isLaunching) {
+            startApplicationsLoader(launcher);
+        }
+    }
+
+    private void startApplicationsLoader(Launcher launcher) {
+        mApplicationsLoader = new ApplicationsLoader(launcher);
+        mLoader = new Thread(mApplicationsLoader, "Applications Loader");
+        mLoader.start();
+    }
+
+    private class ApplicationsLoader implements Runnable {
+        private final WeakReference<Launcher> mLauncher;
+
+        private volatile boolean mStopped;
+        private volatile boolean mRunning;
+
+        ApplicationsLoader(Launcher launcher) {
+            mLauncher = new WeakReference<Launcher>(launcher);
+        }
+
+        void stop() {
+            mStopped = true;
+        }
+
+        boolean isRunning() {
+            return mRunning;
+        }
+
+        public void run() {
+            mRunning = true;
+
+            android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+            final Launcher launcher = mLauncher.get();
+            final PackageManager manager = launcher.getPackageManager();
+            final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
+
+            if (apps != null && !mStopped) {
+                final int count = apps.size();
+                final ApplicationsAdapter applicationList = mApplicationsAdapter;
+
+                ChangeNotifier action = new ChangeNotifier(applicationList);
+
+                for (int i = 0; i < count && !mStopped; i++) {
+                    ApplicationInfo application = new ApplicationInfo();
+                    ResolveInfo info = apps.get(i);
+
+                    application.title = info.loadLabel(manager);
+                    if (application.title == null) {
+                        application.title = info.activityInfo.name;
+                    }
+                    application.setActivity(new ComponentName(
+                            info.activityInfo.applicationInfo.packageName,
+                            info.activityInfo.name),
+                            Intent.FLAG_ACTIVITY_NEW_TASK |
+                            Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                    application.icon = info.activityInfo.loadIcon(manager);
+                    application.container = ItemInfo.NO_ID;
+
+                    action.add(application);
+                }
+
+                action.sort(new Comparator<ApplicationInfo>() {
+                    public final int compare(ApplicationInfo a, ApplicationInfo b) {
+                        return sCollator.compare(a.title.toString(), b.title.toString());
+                    }
+                });
+
+                if (!mStopped) {
+                    launcher.runOnUiThread(action);
+                }
+            }
+
+            if (!mStopped) {
+                mApplicationsLoaded = true;
+            }
+            mRunning = false;
+        }
+    }
+
+    private static class ChangeNotifier implements Runnable {
+        private final ApplicationsAdapter mApplicationList;
+        private ArrayList<ApplicationInfo> mBuffer;
+
+        ChangeNotifier(ApplicationsAdapter applicationList) {
+            mApplicationList = applicationList;
+            mBuffer = new ArrayList<ApplicationInfo>(UI_NOTIFICATION_RATE);
+        }
+
+        public void run() {
+            final ArrayList<ApplicationInfo> buffer = mBuffer;
+            final ApplicationsAdapter applicationList = mApplicationList;
+            final int count = buffer.size();
+
+            applicationList.setNotifyOnChange(false);
+            applicationList.clear();
+            for (int i = 0; i < count; i++) {
+                applicationList.setNotifyOnChange(false);
+                applicationList.add(buffer.get(i));
+            }
+
+            applicationList.notifyDataSetChanged();
+            buffer.clear();
+        }
+
+        void add(ApplicationInfo application) {
+            mBuffer.add(application);
+        }
+
+        void sort(Comparator<ApplicationInfo> comparator) {
+            Collections.sort(mBuffer, comparator);
+        }
+    }
+
+    boolean isDesktopLoaded() {
+        return mDesktopItems != null && mDesktopGadgets != null && mDesktopItemsLoaded;
+    }
+    
+    /**
+     * Loads all of the items on the desktop, in folders, or in the dock.
+     * These can be apps, shortcuts or widgets
+     */
+    void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
+            boolean loadApplications) {
+
+        if (isLaunching && isDesktopLoaded()) {
+            if (loadApplications) startApplicationsLoader(launcher);
+            // We have already loaded our data from the DB
+            launcher.onDesktopItemsLoaded();
+            return;
+        }
+
+        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
+            mDesktopItemsLoader.stop();
+            // Wait for the currently running thread to finish, this can take a little
+            // time but it should be well below the timeout limit
+            try {
+                mDesktopLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
+            } catch (InterruptedException e) {
+                // Empty
+            }
+        }
+
+        mDesktopItemsLoaded = false;
+        mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
+        mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
+        mDesktopLoader.start();
+    }
+
+    private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
+        final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
+                new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.TITLE,
+                        LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
+                null, null, null);
+
+        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
+        final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+        final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+        final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
+
+        // boolean changed = false;
+
+        try {
+            while (c.moveToNext()) {
+                try {
+                    if (c.getInt(itemTypeIndex) !=
+                            LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+                        continue;
+                    }
+
+                    final String intentUri = c.getString(intentIndex);
+                    if (intentUri != null) {
+                        final Intent shortcut = Intent.getIntent(intentUri);
+                        if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
+                            final ComponentName name = shortcut.getComponent();
+                            if (name != null) {
+                                final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
+                                final String title = c.getString(titleIndex);
+                                String label = getLabel(manager, activityInfo);
+
+                                if (title == null || !title.equals(label)) {
+                                    final ContentValues values = new ContentValues();
+                                    values.put(LauncherSettings.Favorites.TITLE, label);
+
+                                    resolver.update(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
+                                            values, "_id=?",
+                                            new String[] { String.valueOf(c.getLong(idIndex)) });
+
+                                    // changed = true;
+                                }
+                            }
+                        }
+                    }
+                } catch (URISyntaxException e) {
+                    // Ignore
+                } catch (PackageManager.NameNotFoundException e) {
+                    // Ignore
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        // if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);
+    }
+
+    private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
+        String label = activityInfo.loadLabel(manager).toString();
+        if (label == null) {
+            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
+            if (label == null) {
+                label = activityInfo.name;
+            }
+        }
+        return label;
+    }
+
+    private class DesktopItemsLoader implements Runnable {
+        private volatile boolean mStopped;
+        private volatile boolean mRunning;
+
+        private final WeakReference<Launcher> mLauncher;
+        private final boolean mLocaleChanged;
+        private final boolean mLoadApplications;
+
+        DesktopItemsLoader(Launcher launcher, boolean localeChanged, boolean loadApplications) {
+            mLoadApplications = loadApplications;
+            mLauncher = new WeakReference<Launcher>(launcher);
+            mLocaleChanged = localeChanged;
+        }
+
+        void stop() {
+            mStopped = true;
+        }
+
+        boolean isRunning() {
+            return mRunning;
+        }
+
+        public void run() {
+            mRunning = true;
+
+            final Launcher launcher = mLauncher.get();
+            final ContentResolver contentResolver = launcher.getContentResolver();
+            final PackageManager manager = launcher.getPackageManager();
+
+            if (mLocaleChanged) {
+                updateShortcutLabels(contentResolver, manager);
+            }
+
+            mDesktopItems = new ArrayList<ItemInfo>();
+            mDesktopGadgets = new ArrayList<LauncherGadgetInfo>();
+            mFolders = new HashMap<Long, FolderInfo>();
+
+            final ArrayList<ItemInfo> desktopItems = mDesktopItems;
+            final ArrayList<LauncherGadgetInfo> desktopGadgets = mDesktopGadgets;
+
+            final Cursor c = contentResolver.query(
+                    LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
+
+            try {
+                final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
+                final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
+                final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
+                final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
+                final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
+                final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
+                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
+                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+                final int gadgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.GADGET_ID);
+                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+                final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
+                final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
+                final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
+                final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
+
+                ApplicationInfo info;
+                String intentDescription;
+                Widget widgetInfo;
+                LauncherGadgetInfo gadgetInfo;
+                int container;
+                long id;
+                Intent intent;
+
+                final HashMap<Long, FolderInfo> folders = mFolders;
+
+                while (!mStopped && c.moveToNext()) {
+                    try {
+                        int itemType = c.getInt(itemTypeIndex);
+
+                        switch (itemType) {
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                            intentDescription = c.getString(intentIndex);
+                            try {
+                                intent = Intent.getIntent(intentDescription);
+                            } catch (java.net.URISyntaxException e) {
+                                continue;
+                            }
+
+                            if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+                                info = getApplicationInfo(manager, intent);
+                            } else {
+                                info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
+                                        iconPackageIndex, iconResourceIndex, iconIndex);
+                            }
+
+                            if (info == null) {
+                                info = new ApplicationInfo();
+                                info.icon = manager.getDefaultActivityIcon();
+                            }
+
+                            if (info != null) {
+                                info.title = c.getString(titleIndex);
+                                info.intent = intent;
+
+                                info.id = c.getLong(idIndex);
+                                container = c.getInt(containerIndex);
+                                info.container = container;
+                                info.screen = c.getInt(screenIndex);
+                                info.cellX = c.getInt(cellXIndex);
+                                info.cellY = c.getInt(cellYIndex);
+
+                                switch (container) {
+                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
+                                    desktopItems.add(info);
+                                    break;
+                                default:
+                                    // Item is in a user folder
+                                    UserFolderInfo folderInfo =
+                                            findOrMakeUserFolder(folders, container);
+                                    folderInfo.add(info);
+                                    break;
+                                }
+                            }
+                            break;
+                        case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+
+                            id = c.getLong(idIndex);
+                            UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
+
+                            folderInfo.title = c.getString(titleIndex);
+
+                            folderInfo.id = id;
+                            container = c.getInt(containerIndex);
+                            folderInfo.container = container;
+                            folderInfo.screen = c.getInt(screenIndex);
+                            folderInfo.cellX = c.getInt(cellXIndex);
+                            folderInfo.cellY = c.getInt(cellYIndex);
+
+                            switch (container) {
+                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
+                                    desktopItems.add(folderInfo);
+                                    break;
+                            }
+                            break;
+                        case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
+
+                            id = c.getLong(idIndex);
+                            LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
+
+                            intentDescription = c.getString(intentIndex);
+                            intent = null;
+                            if (intentDescription != null) {
+                                try {
+                                    intent = Intent.getIntent(intentDescription);
+                                } catch (java.net.URISyntaxException e) {
+                                    // Ignore, a live folder might not have a base intent
+                                }
+                            }
+
+                            liveFolderInfo.title = c.getString(titleIndex);
+                            liveFolderInfo.id = id;
+                            container = c.getInt(containerIndex);
+                            liveFolderInfo.container = container;
+                            liveFolderInfo.screen = c.getInt(screenIndex);
+                            liveFolderInfo.cellX = c.getInt(cellXIndex);
+                            liveFolderInfo.cellY = c.getInt(cellYIndex);
+                            liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
+                            liveFolderInfo.baseIntent = intent;
+                            liveFolderInfo.displayMode = c.getInt(displayModeIndex);
+
+                            loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex,
+                                    iconResourceIndex, liveFolderInfo);
+
+                            switch (container) {
+                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
+                                    desktopItems.add(liveFolderInfo);
+                                    break;
+                            }
+                            break;
+                        case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
+                            widgetInfo = Widget.makeSearch();
+
+                            container = c.getInt(containerIndex);
+                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                                Log.e(Launcher.LOG_TAG, "Widget found where container "
+                                        + "!= CONTAINER_DESKTOP  ignoring!");
+                                continue;
+                            }
+                            
+                            widgetInfo.id = c.getLong(idIndex);
+                            widgetInfo.screen = c.getInt(screenIndex);
+                            widgetInfo.container = container;
+                            widgetInfo.cellX = c.getInt(cellXIndex);
+                            widgetInfo.cellY = c.getInt(cellYIndex);
+
+                            desktopItems.add(widgetInfo);
+                            break;
+                        case LauncherSettings.Favorites.ITEM_TYPE_GADGET:
+                            // Read all Launcher-specific gadget details
+                            int gadgetId = c.getInt(gadgetIdIndex);
+                            gadgetInfo = new LauncherGadgetInfo(gadgetId);
+                            gadgetInfo.id = c.getLong(idIndex);
+                            gadgetInfo.screen = c.getInt(screenIndex);
+                            gadgetInfo.cellX = c.getInt(cellXIndex);
+                            gadgetInfo.cellY = c.getInt(cellYIndex);
+                            gadgetInfo.spanX = c.getInt(spanXIndex);
+                            gadgetInfo.spanY = c.getInt(spanYIndex);
+
+                            container = c.getInt(containerIndex);
+                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                                Log.e(Launcher.LOG_TAG, "Gadget found where container "
+                                        + "!= CONTAINER_DESKTOP -- ignoring!");
+                                continue;
+                            }
+                            gadgetInfo.container = c.getInt(containerIndex);
+                            
+                            desktopGadgets.add(gadgetInfo);
+                            break;
+                        }
+                    } catch (Exception e) {
+                        Log.w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            if (!mStopped) {
+                launcher.runOnUiThread(new Runnable() {
+                    public void run() {
+                        launcher.onDesktopItemsLoaded();
+                    }
+                });
+                if (mLoadApplications) startApplicationsLoader(launcher);
+            }
+
+            if (!mStopped) {
+                mDesktopItemsLoaded = true;
+            }
+            mRunning = false;
+        }
+    }
+
+    private static void loadLiveFolderIcon(Launcher launcher, Cursor c, int iconTypeIndex,
+            int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
+
+        int iconType = c.getInt(iconTypeIndex);
+        switch (iconType) {
+            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
+                String packageName = c.getString(iconPackageIndex);
+                String resourceName = c.getString(iconResourceIndex);
+                PackageManager packageManager = launcher.getPackageManager();
+                try {
+                    Resources resources = packageManager.getResourcesForApplication(packageName);
+                    final int id = resources.getIdentifier(resourceName, null, null);
+                    liveFolderInfo.icon = resources.getDrawable(id);
+                } catch (Exception e) {
+                    liveFolderInfo.icon =
+                            launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
+                }
+                liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
+                liveFolderInfo.iconResource.packageName = packageName;
+                liveFolderInfo.iconResource.resourceName = resourceName;
+                break;
+            default:
+                liveFolderInfo.icon =
+                        launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);                                    
+        }
+    }
+
+    /**
+     * Finds the user folder defined by the specified id.
+     *
+     * @param id The id of the folder to look for.
+     * 
+     * @return A UserFolderInfo if the folder exists or null otherwise.
+     */
+    FolderInfo findFolderById(long id) {
+        return mFolders.get(id);
+    }
+
+    void addFolder(FolderInfo info) {
+        mFolders.put(info.id, info);
+    }
+
+    /**
+     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
+     * new one.
+     */
+    private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
+        // See if a placeholder was created for us already
+        FolderInfo folderInfo = folders.get(id);
+        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
+            // No placeholder -- create a new instance
+            folderInfo = new UserFolderInfo();
+            folders.put(id, folderInfo);
+        }
+        return (UserFolderInfo) folderInfo;
+    }
+
+    /**
+     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
+     * new one.
+     */
+    private LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
+        // See if a placeholder was created for us already
+        FolderInfo folderInfo = folders.get(id);
+        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
+            // No placeholder -- create a new instance
+            folderInfo = new LiveFolderInfo();
+            folders.put(id, folderInfo);
+        }
+        return (LiveFolderInfo) folderInfo;
+    }
+
+    /**
+     * Remove the callback for the cached drawables or we leak the previous
+     * Home screen on orientation change.
+     */
+    void unbind() {
+        mApplicationsAdapter = null;
+        unbindAppDrawables(mApplications);
+        unbindDrawables(mDesktopItems);
+        unbindGadgetHostViews(mDesktopGadgets);
+    }
+    
+    /**
+     * Remove the callback for the cached drawables or we leak the previous
+     * Home screen on orientation change.
+     */
+    private void unbindDrawables(ArrayList<ItemInfo> desktopItems) {
+        if (desktopItems != null) {
+            final int count = desktopItems.size();
+            for (int i = 0; i < count; i++) {
+                ItemInfo item = desktopItems.get(i);
+                switch (item.itemType) {
+                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                    ((ApplicationInfo)item).icon.setCallback(null);
+                    break;
+                }
+            }
+        }
+    }
+    
+    /**
+     * Remove the callback for the cached drawables or we leak the previous
+     * Home screen on orientation change.
+     */
+    private void unbindAppDrawables(ArrayList<ApplicationInfo> applications) {
+        if (applications != null) {
+            final int count = applications.size();
+            for (int i = 0; i < count; i++) {
+                applications.get(i).icon.setCallback(null);
+            }
+        }
+    }
+
+    /**
+     * Remove any {@link LauncherGadgetHostView} references in our gadgets.
+     */
+    private void unbindGadgetHostViews(ArrayList<LauncherGadgetInfo> gadgets) {
+        if (gadgets != null) {
+            final int count = gadgets.size();
+            for (int i = 0; i < count; i++) {
+                LauncherGadgetInfo launcherInfo = gadgets.get(i);
+                launcherInfo.hostView = null;
+            }
+        }
+    }
+
+    /**
+     * @return The current list of applications
+     */
+    public ArrayList<ApplicationInfo> getApplications() {
+        return mApplications;
+    }
+
+    /**
+     * @return The current list of applications
+     */
+    public ApplicationsAdapter getApplicationsAdapter() {
+        return mApplicationsAdapter;
+    }
+
+    /**
+     * @return The current list of desktop items
+     */
+    public ArrayList<ItemInfo> getDesktopItems() {
+        return mDesktopItems;
+    }
+    
+    /**
+     * @return The current list of desktop items
+     */
+    public ArrayList<LauncherGadgetInfo> getDesktopGadgets() {
+        return mDesktopGadgets;
+    }
+
+    /**
+     * Add an item to the desktop
+     * @param info
+     */
+    public void addDesktopItem(ItemInfo info) {
+        // TODO: write to DB; also check that folder has been added to folders list
+        mDesktopItems.add(info);
+    }
+    
+    /**
+     * Remove an item from the desktop
+     * @param info
+     */
+    public void removeDesktopItem(ItemInfo info) {
+        // TODO: write to DB; figure out if we should remove folder from folders list
+        mDesktopItems.remove(info);
+    }
+
+    /**
+     * Add a gadget to the desktop
+     */
+    public void addDesktopGadget(LauncherGadgetInfo info) {
+        mDesktopGadgets.add(info);
+    }
+    
+    /**
+     * Remove a gadget from the desktop
+     */
+    public void removeDesktopGadget(LauncherGadgetInfo info) {
+        mDesktopGadgets.remove(info);
+    }
+
+    /**
+     * Make an ApplicationInfo object for an application
+     */
+    private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent) {
+        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
+
+        if (resolveInfo == null) {
+            return null;
+        }
+        
+        final ApplicationInfo info = new ApplicationInfo();
+        final ActivityInfo activityInfo = resolveInfo.activityInfo;
+        info.icon = activityInfo.loadIcon(manager);
+        if (info.title == null || info.title.length() == 0) {
+            info.title = activityInfo.loadLabel(manager);
+        }
+        if (info.title == null) {
+            info.title = "";
+        }
+        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+        return info;
+    }
+    
+    /**
+     * Make an ApplicationInfo object for a sortcut
+     */
+    private ApplicationInfo getApplicationInfoShortcut(Cursor c, Launcher launcher,
+            int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
+
+        final ApplicationInfo info = new ApplicationInfo();
+        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+
+        int iconType = c.getInt(iconTypeIndex);
+        switch (iconType) {
+            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
+                String packageName = c.getString(iconPackageIndex);
+                String resourceName = c.getString(iconResourceIndex);
+                PackageManager packageManager = launcher.getPackageManager();
+                try {
+                    Resources resources = packageManager.getResourcesForApplication(packageName);
+                    final int id = resources.getIdentifier(resourceName, null, null);
+                    info.icon = resources.getDrawable(id);
+                } catch (Exception e) {
+                    info.icon = packageManager.getDefaultActivityIcon();
+                }
+                info.iconResource = new Intent.ShortcutIconResource();
+                info.iconResource.packageName = packageName;
+                info.iconResource.resourceName = resourceName;
+                info.customIcon = false;
+                break;
+            case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
+                byte[] data = c.getBlob(iconIndex);
+                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                info.icon = new FastBitmapDrawable(
+                        Utilities.createBitmapThumbnail(bitmap, launcher));
+                info.filtered = true;
+                info.customIcon = true;
+                break;
+            default:
+                info.icon = launcher.getPackageManager().getDefaultActivityIcon();
+                info.customIcon = false;
+                break;
+        }
+        return info;
+    }
+
+    /**
+     * Remove an item from the in-memory represention of a user folder. Does not change the DB.
+     */
+    void removeUserFolderItem(UserFolderInfo folder, ItemInfo info) {
+        //noinspection SuspiciousMethodCalls
+        folder.contents.remove(info);
+    }
+    
+    /**
+     * Removes a UserFolder from the in-memory list of folders. Does not change the DB.
+     * @param userFolderInfo
+     */
+    void removeUserFolder(UserFolderInfo userFolderInfo) {
+        mFolders.remove(userFolderInfo.id);
+    }
+    
+    /**
+     * Adds an item to the DB if it was not created previously, or move it to a new
+     * <container, screen, cellX, cellY>
+     */
+    static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
+            int screen, int cellX, int cellY) {
+        if (item.container == ItemInfo.NO_ID) {
+            // From all apps
+            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
+        } else {
+            // From somewhere else
+            moveItemInDatabase(context, item, container, screen, cellX, cellY);
+        }
+    }
+    
+    /**
+     * Move an item in the DB to a new <container, screen, cellX, cellY>
+     */
+    static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
+            int cellX, int cellY) {
+        item.container = container;
+        item.screen = screen;
+        item.cellX = cellX;
+        item.cellY = cellY;
+     
+        final ContentValues values = new ContentValues();
+        final ContentResolver cr = context.getContentResolver();
+
+        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
+        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
+        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
+        values.put(LauncherSettings.Favorites.SCREEN, item.screen);
+
+        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
+    }
+
+    /**
+     * Returns true if the shortcuts already exists in the database.
+     * we identify a shortcut by its title and intent.
+     */
+    static boolean shortcutExists(Context context, String title, Intent intent) {
+        final ContentResolver cr = context.getContentResolver();
+        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
+            new String[] { "title", "intent" }, "title=? and intent=?",
+            new String[] { title, intent.toURI() }, null);
+        boolean result = false;
+        try {
+            result = c.moveToFirst();
+        } finally {
+            c.close();
+        }
+        return result;
+    }
+
+    FolderInfo getFolderById(Context context, long id) {
+        final ContentResolver cr = context.getContentResolver();
+        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
+                "_id=? and itemType=? or itemType=?",
+                new String[] { String.valueOf(id),
+                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
+                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
+
+        try {
+            if (c.moveToFirst()) {
+                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
+                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
+                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+
+                FolderInfo folderInfo = null;
+                switch (c.getInt(itemTypeIndex)) {
+                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+                        folderInfo = findOrMakeUserFolder(mFolders, id);
+                        break;
+                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
+                        folderInfo = findOrMakeLiveFolder(mFolders, id);
+                        break;
+                }
+
+                folderInfo.title = c.getString(titleIndex);
+                folderInfo.id = id;
+                folderInfo.container = c.getInt(containerIndex);
+                folderInfo.screen = c.getInt(screenIndex);
+                folderInfo.cellX = c.getInt(cellXIndex);
+                folderInfo.cellY = c.getInt(cellYIndex);
+
+                return folderInfo;
+            }
+        } finally {
+            c.close();
+        }
+
+        return null;
+    }
+
+    /**
+     * Add an item to the database in a specified container. Sets the container, screen, cellX and
+     * cellY fields of the item. Also assigns an ID to the item.
+     */
+    static void addItemToDatabase(Context context, ItemInfo item, long container,
+            int screen, int cellX, int cellY, boolean notify) {
+        item.container = container;
+        item.screen = screen;
+        item.cellX = cellX;
+        item.cellY = cellY;
+        
+        final ContentValues values = new ContentValues();
+        final ContentResolver cr = context.getContentResolver();
+        
+        item.onAddToDatabase(values);
+        
+        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
+                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
+
+        if (result != null) {
+            item.id = Integer.parseInt(result.getPathSegments().get(1));
+        }
+    }
+
+    /**
+     * Update an item to the database in a specified container.
+     */
+    static void updateItemInDatabase(Context context, ItemInfo item) {
+        final ContentValues values = new ContentValues();
+        final ContentResolver cr = context.getContentResolver();
+
+        item.onAddToDatabase(values);
+
+        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
+    }
+    
+    /**
+     * Removes the specified item from the database
+     * @param context
+     * @param item
+     */
+    static void deleteItemFromDatabase(Context context, ItemInfo item) {
+        final ContentResolver cr = context.getContentResolver();
+
+        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
+    }
+
+
+    /**
+     * Remove the contents of the specified folder from the database
+     */
+    static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
+        final ContentResolver cr = context.getContentResolver();
+
+        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
+        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
+                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
+    }
+}
diff --git a/src/com/android/launcher/LauncherProvider.java b/src/com/android/launcher/LauncherProvider.java
new file mode 100644
index 0000000..539d5ae
--- /dev/null
+++ b/src/com/android/launcher/LauncherProvider.java
@@ -0,0 +1,617 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ContentProvider;
+import android.content.Context;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.content.ContentUris;
+import android.content.ContentResolver;
+import android.content.pm.PackageManager;
+import android.content.pm.ActivityInfo;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.gadget.GadgetHost;
+import android.util.Log;
+import android.util.Xml;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.os.*;
+import android.provider.Settings;
+
+import java.io.FileReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import com.android.internal.util.XmlUtils;
+import com.android.launcher.LauncherSettings.Favorites;
+
+public class LauncherProvider extends ContentProvider {
+    private static final String LOG_TAG = "LauncherProvider";
+    private static final boolean LOGD = true;
+
+    private static final String DATABASE_NAME = "launcher.db";
+    
+    private static final int DATABASE_VERSION = 2;
+
+    static final String AUTHORITY = "com.android.launcher.settings";
+    
+    static final String EXTRA_BIND_SOURCES = "com.android.launcher.settings.bindsources";
+    static final String EXTRA_BIND_TARGETS = "com.android.launcher.settings.bindtargets";
+
+    static final String TABLE_FAVORITES = "favorites";
+    static final String PARAMETER_NOTIFY = "notify";
+
+    private SQLiteOpenHelper mOpenHelper;
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        SqlArguments args = new SqlArguments(uri, null, null);
+        if (TextUtils.isEmpty(args.where)) {
+            return "vnd.android.cursor.dir/" + args.table;
+        } else {
+            return "vnd.android.cursor.item/" + args.table;
+        }
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+
+        SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables(args.table);
+
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor result = qb.query(db, projection, args.where, args.args, null, null, sortOrder);
+        result.setNotificationUri(getContext().getContentResolver(), uri);
+
+        return result;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+        SqlArguments args = new SqlArguments(uri);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final long rowId = db.insert(args.table, null, initialValues);
+        if (rowId <= 0) return null;
+
+        uri = ContentUris.withAppendedId(uri, rowId);
+        sendNotify(uri);
+
+        return uri;
+    }
+
+    @Override
+    public int bulkInsert(Uri uri, ContentValues[] values) {
+        SqlArguments args = new SqlArguments(uri);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            int numValues = values.length;
+            for (int i = 0; i < numValues; i++) {
+                if (db.insert(args.table, null, values[i]) < 0) return 0;
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+        sendNotify(uri);
+        return values.length;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = db.delete(args.table, args.where, args.args);
+        if (count > 0) sendNotify(uri);
+
+        return count;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = db.update(args.table, values, args.where, args.args);
+        if (count > 0) sendNotify(uri);
+
+        return count;
+    }
+
+    private void sendNotify(Uri uri) {
+        String notify = uri.getQueryParameter(PARAMETER_NOTIFY);
+        if (notify == null || "true".equals(notify)) {
+            getContext().getContentResolver().notifyChange(uri, null);
+        }
+    }
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+        /**
+         * Path to file containing default favorite packages, relative to ANDROID_ROOT.
+         */
+        private static final String DEFAULT_FAVORITES_PATH = "etc/favorites.xml";
+
+        private static final String TAG_FAVORITES = "favorites";
+        private static final String TAG_FAVORITE = "favorite";
+        private static final String TAG_PACKAGE = "package";
+        private static final String TAG_CLASS = "class";
+
+        private static final String ATTRIBUTE_SCREEN = "screen";
+        private static final String ATTRIBUTE_X = "x";
+        private static final String ATTRIBUTE_Y = "y";
+
+        private final Context mContext;
+        private final GadgetHost mGadgetHost;
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            mContext = context;
+            mGadgetHost = new GadgetHost(context, Launcher.GADGET_HOST_ID);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            if (LOGD) Log.d(LOG_TAG, "creating new launcher database");
+            
+            db.execSQL("CREATE TABLE favorites (" +
+                    "_id INTEGER PRIMARY KEY," +
+                    "title TEXT," +
+                    "intent TEXT," +
+                    "container INTEGER," +
+                    "screen INTEGER," +
+                    "cellX INTEGER," +
+                    "cellY INTEGER," +
+                    "spanX INTEGER," +
+                    "spanY INTEGER," +
+                    "itemType INTEGER," +
+                    "gadgetId INTEGER NOT NULL DEFAULT -1," +
+                    "isShortcut INTEGER," +
+                    "iconType INTEGER," +
+                    "iconPackage TEXT," +
+                    "iconResource TEXT," +
+                    "icon BLOB," +
+                    "uri TEXT," +
+                    "displayMode INTEGER" +
+                    ");");
+
+            // Database was just created, so wipe any previous gadgets
+            if (mGadgetHost != null) {
+                mGadgetHost.deleteHost();
+            }
+            
+            if (!convertDatabase(db)) {
+                // Populate favorites table with initial favorites
+                loadFavorites(db, DEFAULT_FAVORITES_PATH);
+            }
+        }
+
+        private boolean convertDatabase(SQLiteDatabase db) {
+            if (LOGD) Log.d(LOG_TAG, "converting database from an older format, but not onUpgrade");
+            boolean converted = false;
+
+            final Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
+                    "/old_favorites?notify=true");
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor cursor = null;
+
+            try {
+                cursor = resolver.query(uri, null, null, null, null);
+            } catch (Exception e) {
+	            // Ignore
+            }
+
+            // We already have a favorites database in the old provider
+            if (cursor != null && cursor.getCount() > 0) {
+                try {
+                    converted = copyFromCursor(db, cursor) > 0;
+                } finally {
+                    cursor.close();
+                }
+
+                if (converted) {
+                    resolver.delete(uri, null, null);
+                }
+            }
+            
+            if (converted) {
+                // Convert widgets from this import into gadgets
+                if (LOGD) Log.d(LOG_TAG, "converted and now triggering widget upgrade");
+                convertWidgets(db);
+            }
+
+            return converted;
+        }
+
+        private int copyFromCursor(SQLiteDatabase db, Cursor c) {
+            final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
+            final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+            final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
+            final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
+            final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
+            final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
+            final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
+            final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
+            final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+            final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+            final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+            final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+            final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
+            final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
+
+            ContentValues[] rows = new ContentValues[c.getCount()];
+            int i = 0;
+            while (c.moveToNext()) {
+                ContentValues values = new ContentValues(c.getColumnCount());
+                values.put(LauncherSettings.Favorites.ID, c.getLong(idIndex));
+                values.put(LauncherSettings.Favorites.INTENT, c.getString(intentIndex));
+                values.put(LauncherSettings.Favorites.TITLE, c.getString(titleIndex));
+                values.put(LauncherSettings.Favorites.ICON_TYPE, c.getInt(iconTypeIndex));
+                values.put(LauncherSettings.Favorites.ICON, c.getBlob(iconIndex));
+                values.put(LauncherSettings.Favorites.ICON_PACKAGE, c.getString(iconPackageIndex));
+                values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex));
+                values.put(LauncherSettings.Favorites.CONTAINER, c.getInt(containerIndex));
+                values.put(LauncherSettings.Favorites.ITEM_TYPE, c.getInt(itemTypeIndex));
+                values.put(LauncherSettings.Favorites.GADGET_ID, -1);
+                values.put(LauncherSettings.Favorites.SCREEN, c.getInt(screenIndex));
+                values.put(LauncherSettings.Favorites.CELLX, c.getInt(cellXIndex));
+                values.put(LauncherSettings.Favorites.CELLY, c.getInt(cellYIndex));
+                values.put(LauncherSettings.Favorites.URI, c.getString(uriIndex));
+                values.put(LauncherSettings.Favorites.DISPLAY_MODE, c.getInt(displayModeIndex));
+                rows[i++] = values;
+            }
+
+            db.beginTransaction();
+            int total = 0;
+            try {
+                int numValues = rows.length;
+                for (i = 0; i < numValues; i++) {
+                    if (db.insert(TABLE_FAVORITES, null, rows[i]) < 0) {
+                        return 0;
+                    } else {
+                        total++;
+                    }
+                }
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+
+            return total;
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            if (LOGD) Log.d(LOG_TAG, "onUpgrade triggered");
+            
+            int version = oldVersion;
+            if (version == 1) {
+                // upgrade 1 -> 2 added gadgetId column
+                db.beginTransaction();
+                try {
+                    // Insert new column for holding gadgetIds
+                    db.execSQL("ALTER TABLE favorites " +
+                        "ADD COLUMN gadgetId INTEGER NOT NULL DEFAULT -1;");
+                    db.setTransactionSuccessful();
+                    version = 2;
+                } catch (SQLException ex) {
+                    // Old version remains, which means we wipe old data
+                    Log.e(LOG_TAG, ex.getMessage(), ex);
+                } finally {
+                    db.endTransaction();
+                }
+                
+                // Convert existing widgets only if table upgrade was successful
+                if (version == 2) {
+                    convertWidgets(db);
+                }
+            }
+            
+            if (version != DATABASE_VERSION) {
+                Log.w(LOG_TAG, "Destroying all old data.");
+                db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
+                onCreate(db);
+            }
+        }
+        
+        /**
+         * Upgrade existing clock and photo frame widgets into their new gadget
+         * equivalents. This method allocates gadgetIds, and then hands off to
+         * LauncherGadgetBinder to finish the actual binding.
+         */
+        private void convertWidgets(SQLiteDatabase db) {
+            final int[] bindSources = new int[] {
+                    Favorites.ITEM_TYPE_WIDGET_CLOCK,
+                    Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME,
+            };
+            
+            final ArrayList<ComponentName> bindTargets = new ArrayList<ComponentName>();
+            bindTargets.add(new ComponentName("com.android.alarmclock",
+                    "com.android.alarmclock.AnalogGadgetProvider"));
+            bindTargets.add(new ComponentName("com.android.camera",
+                    "com.android.camera.PhotoGadgetProvider"));
+            
+            final String selectWhere = buildOrWhereString(Favorites.ITEM_TYPE, bindSources);
+            
+            Cursor c = null;
+            boolean allocatedGadgets = false;
+            
+            db.beginTransaction();
+            try {
+                // Select and iterate through each matching widget
+                c = db.query(TABLE_FAVORITES, new String[] { Favorites._ID },
+                        selectWhere, null, null, null, null);
+                
+                if (LOGD) Log.d(LOG_TAG, "found upgrade cursor count="+c.getCount());
+                
+                final ContentValues values = new ContentValues();
+                while (c != null && c.moveToNext()) {
+                    long favoriteId = c.getLong(0);
+                    
+                    // Allocate and update database with new gadgetId
+                    try {
+                        int gadgetId = mGadgetHost.allocateGadgetId();
+                        
+                        if (LOGD) Log.d(LOG_TAG, "allocated gadgetId="+gadgetId+" for favoriteId="+favoriteId);
+                        
+                        values.clear();
+                        values.put(LauncherSettings.Favorites.GADGET_ID, gadgetId);
+                        
+                        // Original widgets might not have valid spans when upgrading
+                        values.put(LauncherSettings.Favorites.SPANX, 2);
+                        values.put(LauncherSettings.Favorites.SPANY, 2);
+
+                        String updateWhere = Favorites._ID + "=" + favoriteId;
+                        db.update(TABLE_FAVORITES, values, updateWhere, null);
+                        
+                        allocatedGadgets = true;
+                    } catch (RuntimeException ex) {
+                        Log.e(LOG_TAG, "Problem allocating gadgetId", ex);
+                    }
+                }
+                
+                db.setTransactionSuccessful();
+            } catch (SQLException ex) {
+                Log.w(LOG_TAG, "Problem while allocating gadgetIds for existing widgets", ex);
+            } finally {
+                db.endTransaction();
+                if (c != null) {
+                    c.close();
+                }
+            }
+            
+            // If any gadgetIds allocated, then launch over to binder
+            if (allocatedGadgets) {
+                launchGadgetBinder(bindSources, bindTargets);
+            }
+        }
+
+        /**
+         * Launch the gadget binder that walks through the Launcher database,
+         * binding any matching widgets to the corresponding targets. We can't
+         * bind ourselves because our parent process can't obtain the
+         * BIND_GADGET permission.
+         */
+        private void launchGadgetBinder(int[] bindSources, ArrayList<ComponentName> bindTargets) {
+            final Intent intent = new Intent();
+            intent.setComponent(new ComponentName("com.android.settings",
+                    "com.android.settings.LauncherGadgetBinder"));
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            
+            final Bundle extras = new Bundle();
+            extras.putIntArray(EXTRA_BIND_SOURCES, bindSources);
+            extras.putParcelableArrayList(EXTRA_BIND_TARGETS, bindTargets);
+            intent.putExtras(extras);
+            
+            mContext.startActivity(intent);
+        }
+        
+        /**
+         * Loads the default set of favorite packages from an xml file.
+         *
+         * @param db The database to write the values into
+         * @param subPath The relative path from ANDROID_ROOT to the file to read
+         */
+        private int loadFavorites(SQLiteDatabase db, String subPath) {
+            FileReader favReader;
+
+            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
+            final File favFile = new File(Environment.getRootDirectory(), subPath);
+            try {
+                favReader = new FileReader(favFile);
+            } catch (FileNotFoundException e) {
+                Log.e(LOG_TAG, "Couldn't find or open favorites file " + favFile);
+                return 0;
+            }
+
+            Intent intent = new Intent(Intent.ACTION_MAIN, null);
+            intent.addCategory(Intent.CATEGORY_LAUNCHER);
+            ContentValues values = new ContentValues();
+
+            PackageManager packageManager = mContext.getPackageManager();
+            ActivityInfo info;
+            int i = 0;
+            try {
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(favReader);
+
+                XmlUtils.beginDocument(parser, TAG_FAVORITES);
+
+                while (true) {
+                    XmlUtils.nextElement(parser);
+
+                    String name = parser.getName();
+                    if (!TAG_FAVORITE.equals(name)) {
+                        break;
+                    }
+
+                    String pkg = parser.getAttributeValue(null, TAG_PACKAGE);
+                    String cls = parser.getAttributeValue(null, TAG_CLASS);
+                    try {
+                        ComponentName cn = new ComponentName(pkg, cls);
+                        info = packageManager.getActivityInfo(cn, 0);
+                        intent.setComponent(cn);
+                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        values.put(LauncherSettings.Favorites.INTENT, intent.toURI());
+                        values.put(LauncherSettings.Favorites.TITLE,
+                                info.loadLabel(packageManager).toString());
+                        values.put(LauncherSettings.Favorites.CONTAINER,
+                                LauncherSettings.Favorites.CONTAINER_DESKTOP);
+                        values.put(LauncherSettings.Favorites.ITEM_TYPE,
+                                LauncherSettings.Favorites.ITEM_TYPE_APPLICATION);
+                        values.put(LauncherSettings.Favorites.SCREEN,
+                                parser.getAttributeValue(null, ATTRIBUTE_SCREEN));
+                        values.put(LauncherSettings.Favorites.CELLX,
+                                parser.getAttributeValue(null, ATTRIBUTE_X));
+                        values.put(LauncherSettings.Favorites.CELLY,
+                                parser.getAttributeValue(null, ATTRIBUTE_Y));
+                        values.put(LauncherSettings.Favorites.SPANX, 1);
+                        values.put(LauncherSettings.Favorites.SPANY, 1);
+                        db.insert(TABLE_FAVORITES, null, values);
+                        i++;
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Log.w(LOG_TAG, "Unable to add favorite: " + pkg + "/" + cls, e);
+                    }
+                }
+            } catch (XmlPullParserException e) {
+                Log.w(LOG_TAG, "Got exception parsing favorites.", e);
+            } catch (IOException e) {
+                Log.w(LOG_TAG, "Got exception parsing favorites.", e);
+            }
+            
+            // Add a search box
+            values.clear();
+            values.put(LauncherSettings.Favorites.CONTAINER,
+                    LauncherSettings.Favorites.CONTAINER_DESKTOP);
+            values.put(LauncherSettings.Favorites.ITEM_TYPE,
+                    LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH);
+            values.put(LauncherSettings.Favorites.SCREEN, 2);
+            values.put(LauncherSettings.Favorites.CELLX, 0);
+            values.put(LauncherSettings.Favorites.CELLY, 0);
+            values.put(LauncherSettings.Favorites.SPANX, 4);
+            values.put(LauncherSettings.Favorites.SPANY, 1);
+            db.insert(TABLE_FAVORITES, null, values);
+            
+            final int[] bindSources = new int[] {
+                    Favorites.ITEM_TYPE_WIDGET_CLOCK,
+            };
+            
+            final ArrayList<ComponentName> bindTargets = new ArrayList<ComponentName>();
+            bindTargets.add(new ComponentName("com.android.alarmclock",
+                    "com.android.alarmclock.AnalogGadgetProvider"));
+            
+            boolean allocatedGadgets = false;
+            
+            // Try binding to an analog clock gadget
+            try {
+                int gadgetId = mGadgetHost.allocateGadgetId();
+                
+                values.clear();
+                values.put(LauncherSettings.Favorites.CONTAINER,
+                        LauncherSettings.Favorites.CONTAINER_DESKTOP);
+                values.put(LauncherSettings.Favorites.ITEM_TYPE,
+                        LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK);
+                values.put(LauncherSettings.Favorites.SCREEN, 1);
+                values.put(LauncherSettings.Favorites.CELLX, 1);
+                values.put(LauncherSettings.Favorites.CELLY, 0);
+                values.put(LauncherSettings.Favorites.SPANX, 2);
+                values.put(LauncherSettings.Favorites.SPANY, 2);
+                values.put(LauncherSettings.Favorites.GADGET_ID, gadgetId);
+                db.insert(TABLE_FAVORITES, null, values);
+                
+                allocatedGadgets = true;
+            } catch (RuntimeException ex) {
+                Log.e(LOG_TAG, "Problem allocating gadgetId", ex);
+            }
+
+            // If any gadgetIds allocated, then launch over to binder
+            if (allocatedGadgets) {
+                launchGadgetBinder(bindSources, bindTargets);
+            }
+            
+            return i;
+        }
+    }
+
+    /**
+     * Build a query string that will match any row where the column matches
+     * anything in the values list.
+     */
+    static String buildOrWhereString(String column, int[] values) {
+        StringBuilder selectWhere = new StringBuilder();
+        for (int i = values.length - 1; i >= 0; i--) {
+            selectWhere.append(column).append("=").append(values[i]);
+            if (i > 0) {
+                selectWhere.append(" OR ");
+            }
+        }
+        return selectWhere.toString();
+    }
+
+    static class SqlArguments {
+        public final String table;
+        public final String where;
+        public final String[] args;
+
+        SqlArguments(Uri url, String where, String[] args) {
+            if (url.getPathSegments().size() == 1) {
+                this.table = url.getPathSegments().get(0);
+                this.where = where;
+                this.args = args;
+            } else if (url.getPathSegments().size() != 2) {
+                throw new IllegalArgumentException("Invalid URI: " + url);
+            } else if (!TextUtils.isEmpty(where)) {
+                throw new UnsupportedOperationException("WHERE clause not supported: " + url);
+            } else {
+                this.table = url.getPathSegments().get(0);
+                this.where = "_id=" + ContentUris.parseId(url);                
+                this.args = null;
+            }
+        }
+
+        SqlArguments(Uri url) {
+            if (url.getPathSegments().size() == 1) {
+                table = url.getPathSegments().get(0);
+                where = null;
+                args = null;
+            } else {
+                throw new IllegalArgumentException("Invalid URI: " + url);
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher/LauncherSettings.java b/src/com/android/launcher/LauncherSettings.java
new file mode 100644
index 0000000..461cca4
--- /dev/null
+++ b/src/com/android/launcher/LauncherSettings.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.provider.BaseColumns;
+import android.net.Uri;
+
+/**
+ * Settings related utilities.
+ */
+class LauncherSettings {
+    /**
+     * Favorites. When changing these values, be sure to update
+     * {@link com.android.settings.LauncherGadgetBinder} as needed.
+     */
+    static final class Favorites implements BaseColumns {
+        /**
+         * The content:// style URL for this table
+         */
+        static final Uri CONTENT_URI = Uri.parse("content://" +
+                LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_FAVORITES +
+                "?" + LauncherProvider.PARAMETER_NOTIFY + "=true");
+
+        /**
+         * The content:// style URL for this table. When this Uri is used, no notification is
+         * sent if the content changes.
+         */
+        static final Uri CONTENT_URI_NO_NOTIFICATION = Uri.parse("content://" +
+                LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_FAVORITES +
+                "?" + LauncherProvider.PARAMETER_NOTIFY + "=false");
+
+        /**
+         * The content:// style URL for a given row, identified by its id.
+         *
+         * @param id The row id.
+         * @param notify True to send a notification is the content changes.
+         *
+         * @return The unique content URL for the specified row.
+         */
+        static Uri getContentUri(long id, boolean notify) {
+            return Uri.parse("content://" + LauncherProvider.AUTHORITY +
+                    "/" + LauncherProvider.TABLE_FAVORITES + "/" + id + "?" +
+                    LauncherProvider.PARAMETER_NOTIFY + "=" + notify);
+        }
+
+        /**
+         * The row ID.
+         * <p>Type: INTEGER</p>
+         */
+        static final String ID = "_id";
+
+        /**
+         * Descriptive name of the favorite that can be displayed to the user.
+         * <P>Type: TEXT</P>
+         */
+        static final String TITLE = "title";
+
+        /**
+         * The Intent URL of the favorite, describing what it points to.  This
+         * value is given to {@link android.content.Intent#getIntent} to create
+         * an Intent that can be launched.
+         * <P>Type: TEXT</P>
+         */
+        static final String INTENT = "intent";
+
+        /**
+         * The container holding the favorite
+         * <P>Type: INTEGER</P>
+         */
+        static final String CONTAINER = "container";
+
+        /**
+         * The icon is a resource identified by a package name and an integer id.
+         */
+        static final int CONTAINER_DESKTOP = -100;
+
+        /**
+         * The screen holding the favorite (if container is CONTAINER_DESKTOP)
+         * <P>Type: INTEGER</P>
+         */
+        static final String SCREEN = "screen";
+
+        /**
+         * The X coordinate of the cell holding the favorite
+         * (if container is CONTAINER_DESKTOP or CONTAINER_DOCK)
+         * <P>Type: INTEGER</P>
+         */
+        static final String CELLX = "cellX";
+
+        /**
+         * The Y coordinate of the cell holding the favorite
+         * (if container is CONTAINER_DESKTOP)
+         * <P>Type: INTEGER</P>
+         */
+        static final String CELLY = "cellY";
+
+        /**
+         * The X span of the cell holding the favorite
+         * <P>Type: INTEGER</P>
+         */
+        static final String SPANX = "spanX";
+
+        /**
+         * The Y span of the cell holding the favorite
+         * <P>Type: INTEGER</P>
+         */
+        static final String SPANY = "spanY";
+
+        /**
+         * The type of the favorite
+         *
+         * <P>Type: INTEGER</P>
+         */
+        static final String ITEM_TYPE = "itemType";
+
+        /**
+         * The favorite is an application
+         */
+        static final int ITEM_TYPE_APPLICATION = 0;
+
+        /**
+         * The favorite is an application created shortcut
+         */
+        static final int ITEM_TYPE_SHORTCUT = 1;
+
+        /**
+         * The favorite is a user created folder
+         */
+        static final int ITEM_TYPE_USER_FOLDER = 2;
+
+        /**
+         * The favorite is a live folder
+         */
+        static final int ITEM_TYPE_LIVE_FOLDER = 3;
+
+        /**
+         * The favorite is a gadget
+         */
+        static final int ITEM_TYPE_GADGET = 4;
+
+        /**
+         * The favorite is a clock
+         */
+        static final int ITEM_TYPE_WIDGET_CLOCK = 1000;
+
+        /**
+         * The favorite is a search widget
+         */
+        static final int ITEM_TYPE_WIDGET_SEARCH = 1001;
+
+        /**
+         * The favorite is a photo frame
+         */
+        static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002;
+
+        /**
+         * The gadgetId of the gadget
+         *
+         * <P>Type: INTEGER</P>
+         */
+        static final String GADGET_ID = "gadgetId";
+        
+        /**
+         * Indicates whether this favorite is an application-created shortcut or not.
+         * If the value is 0, the favorite is not an application-created shortcut, if the
+         * value is 1, it is an application-created shortcut.
+         * <P>Type: INTEGER</P>
+         */
+        static final String IS_SHORTCUT = "isShortcut";
+
+        /**
+         * The icon type.
+         * <P>Type: INTEGER</P>
+         */
+        static final String ICON_TYPE = "iconType";
+
+        /**
+         * The icon is a resource identified by a package name and an integer id.
+         */
+        static final int ICON_TYPE_RESOURCE = 0;
+
+        /**
+         * The icon is a bitmap.
+         */
+        static final int ICON_TYPE_BITMAP = 1;
+
+        /**
+         * The icon package name, if icon type is ICON_TYPE_RESOURCE.
+         * <P>Type: TEXT</P>
+         */
+        static final String ICON_PACKAGE = "iconPackage";
+
+        /**
+         * The icon resource id, if icon type is ICON_TYPE_RESOURCE.
+         * <P>Type: TEXT</P>
+         */
+        static final String ICON_RESOURCE = "iconResource";
+
+        /**
+         * The custom icon bitmap, if icon type is ICON_TYPE_BITMAP.
+         * <P>Type: BLOB</P>
+         */
+        static final String ICON = "icon";
+
+        /**
+         * The URI associated with the favorite. It is used, for instance, by
+         * live folders to find the content provider.
+         * <P>Type: TEXT</P>
+         */
+        static final String URI = "uri";
+
+        /**
+         * The display mode if the item is a live folder.
+         * <P>Type: INTEGER</P>
+         *
+         * @see android.provider.LiveFolders#DISPLAY_MODE_GRID
+         * @see android.provider.LiveFolders#DISPLAY_MODE_LIST
+         */
+        static final String DISPLAY_MODE = "displayMode";
+    }
+}
diff --git a/src/com/android/launcher/LiveFolder.java b/src/com/android/launcher/LiveFolder.java
new file mode 100644
index 0000000..5d727f8
--- /dev/null
+++ b/src/com/android/launcher/LiveFolder.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.Intent;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.net.Uri;
+import android.provider.LiveFolders;
+import android.os.AsyncTask;
+import android.database.Cursor;
+
+import java.lang.ref.WeakReference;
+
+public class LiveFolder extends Folder {
+    private AsyncTask<LiveFolderInfo,Void,Cursor> mLoadingTask;
+
+    public LiveFolder(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    static LiveFolder fromXml(Context context, FolderInfo folderInfo) {
+        final int layout = isDisplayModeList(folderInfo) ?
+                R.layout.live_folder_list : R.layout.live_folder_grid;
+        return (LiveFolder) LayoutInflater.from(context).inflate(layout, null);
+    }
+
+    private static boolean isDisplayModeList(FolderInfo folderInfo) {
+        return ((LiveFolderInfo) folderInfo).displayMode ==
+                LiveFolders.DISPLAY_MODE_LIST;
+    }
+
+    @Override
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        LiveFolderAdapter.ViewHolder holder = (LiveFolderAdapter.ViewHolder) v.getTag();
+
+        if (holder.useBaseIntent) {
+            final Intent baseIntent = ((LiveFolderInfo) mInfo).baseIntent;
+            if (baseIntent != null) {
+                final Intent intent = new Intent(baseIntent);
+                Uri uri = baseIntent.getData();
+                uri = uri.buildUpon().appendPath(Long.toString(holder.id)).build();
+                intent.setData(uri);
+                mLauncher.startActivitySafely(intent);
+            }
+        } else if (holder.intent != null) {
+            mLauncher.startActivitySafely(holder.intent);
+        }
+    }
+
+    @Override
+    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+        return false;
+    }
+
+    void bind(FolderInfo info) {
+        super.bind(info);
+        if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
+            mLoadingTask.cancel(true);
+        }
+        mLoadingTask = new FolderLoadingTask(this).execute((LiveFolderInfo) info);
+    }
+
+    @Override
+    void onOpen() {
+        super.onOpen();
+        requestFocus();
+    }
+
+    @Override
+    void onClose() {
+        super.onClose();
+        if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
+            mLoadingTask.cancel(true);
+        }
+        ((LiveFolderAdapter) mContent.getAdapter()).cleanup();
+    }
+
+    static class FolderLoadingTask extends AsyncTask<LiveFolderInfo, Void, Cursor> {
+        private final WeakReference<LiveFolder> mFolder;
+        private LiveFolderInfo mInfo;
+
+        FolderLoadingTask(LiveFolder folder) {
+            mFolder = new WeakReference<LiveFolder>(folder);
+        }
+
+        protected Cursor doInBackground(LiveFolderInfo... params) {
+            final LiveFolder folder = mFolder.get();
+            if (folder != null) {
+                mInfo = params[0];
+                return LiveFolderAdapter.query(folder.mLauncher, mInfo);
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Cursor cursor) {
+            if (!isCancelled()) {
+                if (cursor != null) {
+                    final LiveFolder folder = mFolder.get();
+                    if (folder != null) {
+                        final Launcher launcher = folder.mLauncher;
+                        folder.setContentAdapter(new LiveFolderAdapter(launcher, mInfo, cursor));
+                    }
+                }
+            } else if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher/LiveFolderAdapter.java b/src/com/android/launcher/LiveFolderAdapter.java
new file mode 100644
index 0000000..4a5c077
--- /dev/null
+++ b/src/com/android/launcher/LiveFolderAdapter.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.CursorAdapter;
+import android.widget.TextView;
+import android.widget.ImageView;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.content.pm.PackageManager;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.database.Cursor;
+import android.provider.LiveFolders;
+import android.graphics.drawable.Drawable;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.lang.ref.SoftReference;
+
+class LiveFolderAdapter extends CursorAdapter {
+    private boolean mIsList;
+    private LayoutInflater mInflater;
+
+    private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>();
+    private final HashMap<Long, SoftReference<Drawable>> mCustomIcons =
+            new HashMap<Long, SoftReference<Drawable>>();
+    private final Launcher mLauncher;
+
+    LiveFolderAdapter(Launcher launcher, LiveFolderInfo info, Cursor cursor) {
+        super(launcher, cursor, true);
+        mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST;
+        mInflater = LayoutInflater.from(launcher);
+        mLauncher = launcher;
+
+        mLauncher.startManagingCursor(getCursor());
+    }
+
+    static Cursor query(Context context, LiveFolderInfo info) {
+        return context.getContentResolver().query(info.uri, null, null,
+                null, LiveFolders.NAME + " ASC");
+    }
+
+    public View newView(Context context, Cursor cursor, ViewGroup parent) {
+        View view;
+        final ViewHolder holder = new ViewHolder();
+
+        if (!mIsList) {
+            view = mInflater.inflate(R.layout.application_boxed, parent, false);
+        } else {
+            view = mInflater.inflate(R.layout.application_list, parent, false);
+            holder.description = (TextView) view.findViewById(R.id.description);
+            holder.icon = (ImageView) view.findViewById(R.id.icon);
+        }
+
+        holder.name = (TextView) view.findViewById(R.id.name);
+
+        holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID);
+        holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME);
+        holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION);
+        holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT);
+        holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP);
+        holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE);
+        holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE);
+
+        view.setTag(holder);
+
+        return view;
+    }
+
+    public void bindView(View view, Context context, Cursor cursor) {
+        final ViewHolder holder = (ViewHolder) view.getTag();
+
+        holder.id = cursor.getLong(holder.idIndex);
+        final Drawable icon = loadIcon(context, cursor, holder);
+
+        holder.name.setText(cursor.getString(holder.nameIndex));
+
+        if (!mIsList) {
+            holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
+        } else {
+            final boolean hasIcon = icon != null;
+            holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE);
+            if (hasIcon) holder.icon.setImageDrawable(icon);
+
+            if (holder.descriptionIndex != -1) {
+                final String description = cursor.getString(holder.descriptionIndex);
+                if (description != null) {
+                    holder.description.setText(description);
+                    holder.description.setVisibility(View.VISIBLE);
+                } else {
+                    holder.description.setVisibility(View.GONE);                    
+                }
+            } else {
+                holder.description.setVisibility(View.GONE);                
+            }
+        }
+
+        if (holder.intentIndex != -1) {
+            try {
+                holder.intent = Intent.getIntent(cursor.getString(holder.intentIndex));
+            } catch (URISyntaxException e) {
+                // Ignore
+            }
+        } else {
+            holder.useBaseIntent = true;
+        }
+    }
+
+    private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) {
+        Drawable icon = null;
+        byte[] data = null;
+
+        if (holder.iconBitmapIndex != -1) {
+            data = cursor.getBlob(holder.iconBitmapIndex);
+        }
+
+        if (data != null) {
+            final SoftReference<Drawable> reference = mCustomIcons.get(holder.id);
+            if (reference != null) {
+                icon = reference.get();
+            }
+
+            if (icon == null) {
+                final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, mContext));
+                mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon));
+            }
+        } else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) {
+            final String resource = cursor.getString(holder.iconResourceIndex);
+            icon = mIcons.get(resource);
+            if (icon == null) {
+                try {
+                    final PackageManager packageManager = context.getPackageManager();
+                    Resources resources = packageManager.getResourcesForApplication(
+                            cursor.getString(holder.iconPackageIndex));
+                    final int id = resources.getIdentifier(resource,
+                            null, null);
+                    icon = Utilities.createIconThumbnail(resources.getDrawable(id), mContext);
+                    mIcons.put(resource, icon);
+                } catch (Exception e) {
+                    // Ignore
+                }
+            }
+        }
+
+        return icon;
+    }
+
+    void cleanup() {
+        for (Drawable icon : mIcons.values()) {
+            icon.setCallback(null);
+        }
+        mIcons.clear();
+
+        for (SoftReference<Drawable> icon : mCustomIcons.values()) {
+            final Drawable drawable = icon.get();
+            if (drawable != null) {
+                drawable.setCallback(null);
+            }
+        }
+        mCustomIcons.clear();
+
+        final Cursor cursor = getCursor();
+        if (cursor != null) {
+            try {
+                cursor.close();
+            } finally {
+                mLauncher.stopManagingCursor(cursor);
+            }
+        }
+    }
+
+    static class ViewHolder {
+        TextView name;
+        TextView description;
+        ImageView icon;
+
+        Intent intent;
+        long id;
+        boolean useBaseIntent;
+
+        int idIndex;
+        int nameIndex;
+        int descriptionIndex = -1;
+        int intentIndex = -1;
+        int iconBitmapIndex = -1;
+        int iconResourceIndex = -1;
+        int iconPackageIndex = -1;
+    }
+}
diff --git a/src/com/android/launcher/LiveFolderIcon.java b/src/com/android/launcher/LiveFolderIcon.java
new file mode 100644
index 0000000..33cb0b7
--- /dev/null
+++ b/src/com/android/launcher/LiveFolderIcon.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.graphics.drawable.Drawable;
+
+public class LiveFolderIcon extends FolderIcon {
+    public LiveFolderIcon(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LiveFolderIcon(Context context) {
+        super(context);
+    }
+
+    static LiveFolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
+            LiveFolderInfo folderInfo) {
+
+        LiveFolderIcon icon = (LiveFolderIcon)
+                LayoutInflater.from(launcher).inflate(resId, group, false);
+
+        final Resources resources = launcher.getResources();
+        Drawable d = folderInfo.icon;
+        if (d == null) {
+            resources.getDrawable(R.drawable.ic_launcher_folder);
+            d = Utilities.createIconThumbnail(d, launcher);
+            folderInfo.filtered = true;
+        }
+        icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
+        icon.setText(folderInfo.title);
+        icon.setTag(folderInfo);
+        icon.setOnClickListener(launcher);
+        
+        return icon;
+    }
+
+    @Override
+    public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        return false;
+    }
+
+    @Override
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    @Override
+    public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    @Override
+    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    @Override
+    public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+}
diff --git a/src/com/android/launcher/LiveFolderInfo.java b/src/com/android/launcher/LiveFolderInfo.java
new file mode 100644
index 0000000..2432cc3
--- /dev/null
+++ b/src/com/android/launcher/LiveFolderInfo.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+
+class LiveFolderInfo extends FolderInfo {
+
+    /**
+     * The base intent, if it exists.
+     */
+    Intent baseIntent;
+
+    /**
+     * The live folder's content uri.
+     */
+    Uri uri;
+
+    /**
+     * The live folder's display type.
+     */
+    int displayMode;
+
+    /**
+     * The live folder icon.
+     */
+    Drawable icon;
+
+    /**
+     * When set to true, indicates that the icon has been resized.
+     */
+    boolean filtered;
+
+    /**
+     * Reference to the live folder icon as an application's resource.
+     */
+    Intent.ShortcutIconResource iconResource;
+
+    LiveFolderInfo() {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER;
+    }
+
+    @Override
+    void onAddToDatabase(ContentValues values) {
+        super.onAddToDatabase(values);
+        values.put(LauncherSettings.Favorites.TITLE, title.toString());
+        values.put(LauncherSettings.Favorites.URI, uri.toString());
+        if (baseIntent != null) {
+            values.put(LauncherSettings.Favorites.INTENT, baseIntent.toURI());
+        }
+        values.put(LauncherSettings.Favorites.ICON_TYPE, LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
+        values.put(LauncherSettings.Favorites.DISPLAY_MODE, displayMode);
+        if (iconResource != null) {
+            values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
+            values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
+        }
+    }
+}
diff --git a/src/com/android/launcher/Search.java b/src/com/android/launcher/Search.java
new file mode 100644
index 0000000..296b902
--- /dev/null
+++ b/src/com/android/launcher/Search.java
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2008 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.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.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.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 {
+
+    private final String TAG = "SearchGadget";
+
+    private AutoCompleteTextView mSearchText;
+    private ImageButton mGoButton;
+    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;
+    
+    // For voice searching
+    private Intent mVoiceSearchIntent;
+
+    private Rect mTempRect = new Rect();
+    private boolean mRestoreFocus = false;
+
+    /**
+     * Used to inflate the Workspace from XML.
+     *
+     * @param context The application's context.
+     * @param attrs The attributes set containing the Workspace's customization values.
+     */
+    public Search(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        
+        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)
+     */
+    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");
+            }
+        }
+    }
+
+    private void query() {
+        String query = mSearchText.getText().toString();
+        if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) {
+            return;
+        }
+        Bundle appData = new Bundle();
+        appData.putString(SearchManager.SOURCE, "launcher-widget");
+        sendLaunchIntent(Intent.ACTION_SEARCH, null, query, appData, 0, null, mSearchable);
+        clearQuery();
+    }
+    
+    /**
+     * 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);
+            }
+            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)
+     */
+    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);
+    }
+
+    @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);
+        mVoiceButton = (ImageButton) findViewById(R.id.search_voice_btn);
+        mGoButton.setOnClickListener(this);
+        mVoiceButton.setOnClickListener(this);
+        mGoButton.setOnKeyListener(this);
+        mVoiceButton.setOnKeyListener(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();
+    }
+    
+    /**
+     * 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
+     * 
+     * Note:  Because the home screen search widget is always web search, we only check for
+     * getVoiceSearchLaunchWebSearch() modes.  We don't support the alternate form of app-specific
+     * 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;
+        }
+        
+        // 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
+     */
+    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);
+    }
+    
+    /**
+     * 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
+     */
+     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.
+         */
+        @Override
+        public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+            String query = (constraint == null) ? "" : constraint.toString();
+            return getSuggestions(mSearchable, query);
+        }
+        
+        /**
+         * 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;
+            }
+        }
+
+    }
+}
diff --git a/src/com/android/launcher/SearchAutoCompleteTextView.java b/src/com/android/launcher/SearchAutoCompleteTextView.java
new file mode 100644
index 0000000..4f0df18
--- /dev/null
+++ b/src/com/android/launcher/SearchAutoCompleteTextView.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.widget.AutoCompleteTextView;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.AttributeSet;
+import android.graphics.Rect;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.app.Activity;
+
+/**
+ * This class is not for the faint of heart. Home works in the pan & scan
+ * soft input mode. However, this mode gets rid of the soft keyboard on rotation,
+ * which is a probelm when the Search widget has focus. This special class
+ * changes Home's soft input method temporarily as long as the Search widget holds
+ * the focus. This way, the soft keyboard remains after rotation.
+ */
+public class SearchAutoCompleteTextView extends AutoCompleteTextView {
+    private boolean mShowKeyboard;
+
+    public SearchAutoCompleteTextView(Context context) {
+        super(context);
+    }
+
+    public SearchAutoCompleteTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public SearchAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+
+        final WindowManager.LayoutParams lp = ((Activity) getContext()).getWindow().getAttributes();
+        if (gainFocus) {
+            lp.softInputMode =
+                    (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) |
+                            WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
+        } else {
+            //noinspection PointlessBitwiseExpression
+            lp.softInputMode =
+                    (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) |
+                            WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
+
+            // Hide the soft keyboard when the search widget loses the focus
+            InputMethodManager.peekInstance().hideSoftInputFromWindow(getWindowToken(), 0);
+        }
+
+        final WindowManager manager = (WindowManager)
+                getContext().getSystemService(Context.WINDOW_SERVICE);
+        manager.updateViewLayout(getRootView(), lp);
+
+        if (mShowKeyboard) {
+            if (getContext().getResources().getConfiguration().hardKeyboardHidden ==
+                    Configuration.HARDKEYBOARDHIDDEN_YES) {
+                InputMethodManager inputManager = (InputMethodManager)
+                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                inputManager.showSoftInput(this, 0);
+            }
+            mShowKeyboard = false;
+        }
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        // See Workspace#focusOnSearch()
+        setFocusableInTouchMode(false);
+    }
+
+    void showKeyboardOnNextFocus() {
+        mShowKeyboard = true;
+    }
+}
diff --git a/src/com/android/launcher/UninstallShortcutReceiver.java b/src/com/android/launcher/UninstallShortcutReceiver.java
new file mode 100644
index 0000000..e490f9c
--- /dev/null
+++ b/src/com/android/launcher/UninstallShortcutReceiver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+
+import java.net.URISyntaxException;
+
+public class UninstallShortcutReceiver extends BroadcastReceiver {
+    public void onReceive(Context context, Intent data) {
+        Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+        String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+        boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
+
+        if (intent != null && name != null) {
+            final ContentResolver cr = context.getContentResolver();
+            Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
+                new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.INTENT },
+                LauncherSettings.Favorites.TITLE + "=?", new String[] { name }, null);
+
+            final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+            final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
+
+            boolean changed = false;
+
+            try {
+                while (c.moveToNext()) {
+                    try {
+                        if (intent.filterEquals(Intent.getIntent(c.getString(intentIndex)))) {
+                            final long id = c.getLong(idIndex);
+                            final Uri uri = LauncherSettings.Favorites.getContentUri(id, false);
+                            cr.delete(uri, null, null);
+                            changed = true;
+                            if (!duplicate) {
+                                break;
+                            }
+                        }
+                    } catch (URISyntaxException e) {
+                        // Ignore
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            if (changed) cr.notifyChange(LauncherSettings.Favorites.CONTENT_URI, null);
+        }
+    }
+}
diff --git a/src/com/android/launcher/UserFolder.java b/src/com/android/launcher/UserFolder.java
new file mode 100644
index 0000000..1044e96
--- /dev/null
+++ b/src/com/android/launcher/UserFolder.java
@@ -0,0 +1,75 @@
+package com.android.launcher;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ArrayAdapter;
+
+/**
+ * Folder which contains applications or shortcuts chosen by the user.
+ *
+ */
+public class UserFolder extends Folder implements DropTarget {
+    public UserFolder(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+    
+    /**
+     * Creates a new UserFolder, inflated from R.layout.user_folder.
+     *
+     * @param context The application's context.
+     *
+     * @return A new UserFolder.
+     */
+    static UserFolder fromXml(Context context) {
+        return (UserFolder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
+    }
+
+    public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+        final ItemInfo item = (ItemInfo) dragInfo;
+        final int itemType = item.itemType;
+        return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+                itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && item.container != mInfo.id;
+    }
+
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        final ApplicationInfo item = (ApplicationInfo) dragInfo;
+        //noinspection unchecked
+        ((ArrayAdapter<ApplicationInfo>) mContent.getAdapter()).add((ApplicationInfo) dragInfo);
+        LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
+    }
+
+    public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+    }
+
+    @Override
+    public void onDropCompleted(View target, boolean success) {
+        if (success) {
+            //noinspection unchecked
+            ArrayAdapter<ApplicationInfo> adapter =
+                    (ArrayAdapter<ApplicationInfo>) mContent.getAdapter();
+            adapter.remove(mDragItem);
+        }
+    }
+
+    void bind(FolderInfo info) {
+        super.bind(info);
+        setContentAdapter(new ApplicationsAdapter(mContext, ((UserFolderInfo) info).contents));
+    }
+
+    // When the folder opens, we need to refresh the GridView's selection by
+    // forcing a layout
+    @Override
+    void onOpen() {
+        super.onOpen();
+        requestFocus();
+    }
+}
diff --git a/src/com/android/launcher/UserFolderInfo.java b/src/com/android/launcher/UserFolderInfo.java
new file mode 100644
index 0000000..639894e
--- /dev/null
+++ b/src/com/android/launcher/UserFolderInfo.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ContentValues;
+
+import java.util.ArrayList;
+
+/**
+ * Represents a folder containing shortcuts or apps.
+ */
+class UserFolderInfo extends FolderInfo {
+    /**
+     * The apps and shortcuts 
+     */
+    ArrayList<ApplicationInfo> contents = new ArrayList<ApplicationInfo>();
+    
+    UserFolderInfo() {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER;
+    }
+    
+    /**
+     * Add an app or shortcut
+     * 
+     * @param item
+     */
+    public void add(ApplicationInfo item) {
+        contents.add(item);
+    }
+    
+    /**
+     * Remove an app or shortcut
+     * 
+     * @param item
+     */
+    public void remove(ApplicationInfo item) {
+        contents.remove(item);
+    }
+    
+    @Override
+    void onAddToDatabase(ContentValues values) { 
+        super.onAddToDatabase(values);
+        values.put(LauncherSettings.Favorites.TITLE, title.toString());
+    }
+}
diff --git a/src/com/android/launcher/Utilities.java b/src/com/android/launcher/Utilities.java
new file mode 100644
index 0000000..cb8976c
--- /dev/null
+++ b/src/com/android/launcher/Utilities.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.PaintDrawable;
+import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.graphics.Canvas;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.content.res.Resources;
+import android.content.Context;
+
+/**
+ * Various utilities shared amongst the Launcher's classes.
+ */
+final class Utilities {
+    private static int sIconWidth = -1;
+    private static int sIconHeight = -1;
+
+    private static final Paint sPaint = new Paint();
+    private static final Rect sBounds = new Rect();
+    private static final Rect sOldBounds = new Rect();
+    private static Canvas sCanvas = new Canvas();
+
+    static {
+        sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
+                Paint.FILTER_BITMAP_FLAG));
+    }
+
+    static Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) {
+        final int bitmapWidth = bitmap.getWidth();
+        final int bitmapHeight = bitmap.getHeight();
+
+        if (bitmapWidth < width || bitmapHeight < height) {
+            int color = context.getResources().getColor(R.color.window_background);
+
+            Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth,
+                    bitmapHeight < height ? height : bitmapHeight, Bitmap.Config.RGB_565);
+            Canvas canvas = new Canvas(centered);
+            canvas.drawColor(color);
+            canvas.drawBitmap(bitmap, (width - bitmapWidth) / 2.0f, (height - bitmapHeight) / 2.0f,
+                    null);
+
+            bitmap = centered;
+        }
+
+        return bitmap;
+    }
+
+    /**
+     * Returns a Drawable representing the thumbnail of the specified Drawable.
+     * The size of the thumbnail is defined by the dimension
+     * android.R.dimen.launcher_application_icon_size.
+     *
+     * This method is not thread-safe and should be invoked on the UI thread only.
+     *
+     * @param icon The icon to get a thumbnail of.
+     * @param context The application's context.
+     *
+     * @return A thumbnail for the specified icon or the icon itself if the
+     *         thumbnail could not be created. 
+     */
+    static Drawable createIconThumbnail(Drawable icon, Context context) {
+        if (sIconWidth == -1) {
+            final Resources resources = context.getResources();
+            sIconWidth = sIconHeight = (int) resources.getDimension(
+                    android.R.dimen.app_icon_size);
+        }
+
+        int width = sIconWidth;
+        int height = sIconHeight;
+
+        final int iconWidth = icon.getIntrinsicWidth();
+        final int iconHeight = icon.getIntrinsicHeight();
+
+        if (icon instanceof PaintDrawable) {
+            PaintDrawable painter = (PaintDrawable) icon;
+            painter.setIntrinsicWidth(width);
+            painter.setIntrinsicHeight(height);
+        }
+
+        if (width > 0 && height > 0) {
+            if (width < iconWidth || height < iconHeight) {
+                final float ratio = (float) iconWidth / iconHeight;
+
+                if (iconWidth > iconHeight) {
+                    height = (int) (width / ratio);
+                } else if (iconHeight > iconWidth) {
+                    width = (int) (height * ratio);
+                }
+
+                final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
+                            Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+                final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
+                final Canvas canvas = sCanvas;
+                canvas.setBitmap(thumb);
+                // Copy the old bounds to restore them later
+                // If we were to do oldBounds = icon.getBounds(),
+                // the call to setBounds() that follows would
+                // change the same instance and we would lose the
+                // old bounds
+                sOldBounds.set(icon.getBounds());
+                final int x = (sIconWidth - width) / 2;
+                final int y = (sIconHeight - height) / 2;
+                icon.setBounds(x, y, x + width, y + height);
+                icon.draw(canvas);
+                icon.setBounds(sOldBounds);
+                icon = new FastBitmapDrawable(thumb);
+            } else if (iconWidth < width && iconHeight < height) {
+                final Bitmap.Config c = Bitmap.Config.ARGB_8888;
+                final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
+                final Canvas canvas = sCanvas;
+                canvas.setBitmap(thumb);
+                sOldBounds.set(icon.getBounds());
+                final int x = (width - iconWidth) / 2;
+                final int y = (height - iconHeight) / 2;
+                icon.setBounds(x, y, x + iconWidth, y + iconHeight);
+                icon.draw(canvas);
+                icon.setBounds(sOldBounds);
+                icon = new FastBitmapDrawable(thumb);
+            }
+        }
+
+        return icon;
+    }
+
+    /**
+     * Returns a Bitmap representing the thumbnail of the specified Bitmap.
+     * The size of the thumbnail is defined by the dimension
+     * android.R.dimen.launcher_application_icon_size.
+     *
+     * This method is not thread-safe and should be invoked on the UI thread only.
+     *
+     * @param bitmap The bitmap to get a thumbnail of.
+     * @param context The application's context.
+     *
+     * @return A thumbnail for the specified bitmap or the bitmap itself if the
+     *         thumbnail could not be created.
+     */
+    static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context) {
+        if (sIconWidth == -1) {
+            final Resources resources = context.getResources();
+            sIconWidth = sIconHeight = (int) resources.getDimension(
+                    android.R.dimen.app_icon_size);
+        }
+
+        int width = sIconWidth;
+        int height = sIconHeight;
+
+        final int bitmapWidth = bitmap.getWidth();
+        final int bitmapHeight = bitmap.getHeight();
+
+        if (width > 0 && height > 0 && (width < bitmapWidth || height < bitmapHeight)) {
+            final float ratio = (float) bitmapWidth / bitmapHeight;
+
+            if (bitmapWidth > bitmapHeight) {
+                height = (int) (width / ratio);
+            } else if (bitmapHeight > bitmapWidth) {
+                width = (int) (height * ratio);
+            }
+
+            final Bitmap.Config c = (width == sIconWidth && height == sIconHeight) ?
+                    bitmap.getConfig() : Bitmap.Config.ARGB_8888;
+            final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
+            final Canvas canvas = sCanvas;
+            final Paint paint = sPaint;
+            canvas.setBitmap(thumb);
+            paint.setDither(false);
+            paint.setFilterBitmap(true);
+            sBounds.set((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height);
+            sOldBounds.set(0, 0, bitmapWidth, bitmapHeight);
+            canvas.drawBitmap(bitmap, sOldBounds, sBounds, paint);
+            return thumb;
+        }
+
+        return bitmap;
+    }
+}
diff --git a/src/com/android/launcher/WallpaperChooser.java b/src/com/android/launcher/WallpaperChooser.java
new file mode 100644
index 0000000..9ac922c
--- /dev/null
+++ b/src/com/android/launcher/WallpaperChooser.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.Gallery;
+import android.widget.ImageView;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.content.res.Resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class WallpaperChooser extends Activity implements AdapterView.OnItemSelectedListener,
+        OnClickListener {
+
+    private static final Integer[] THUMB_IDS = {
+            R.drawable.wallpaper_lake_small,
+            R.drawable.wallpaper_sunset_small,
+            R.drawable.wallpaper_beach_small,
+            R.drawable.wallpaper_snow_leopard_small,
+            R.drawable.wallpaper_path_small,
+            R.drawable.wallpaper_sunrise_small,
+            R.drawable.wallpaper_mountain_small,
+            R.drawable.wallpaper_road_small,
+            R.drawable.wallpaper_jellyfish_small,
+            R.drawable.wallpaper_zanzibar_small,
+            R.drawable.wallpaper_blue_small,
+            R.drawable.wallpaper_grey_small,
+            R.drawable.wallpaper_green_small,
+            R.drawable.wallpaper_pink_small,
+    };
+
+    private static final Integer[] IMAGE_IDS = {
+            com.android.internal.R.drawable.default_wallpaper,
+            R.drawable.wallpaper_sunset,
+            R.drawable.wallpaper_beach,
+            R.drawable.wallpaper_snow_leopard,
+            R.drawable.wallpaper_path,
+            R.drawable.wallpaper_sunrise,
+            R.drawable.wallpaper_mountain,
+            R.drawable.wallpaper_road,
+            R.drawable.wallpaper_jellyfish,
+            R.drawable.wallpaper_zanzibar,
+            R.drawable.wallpaper_blue,
+            R.drawable.wallpaper_grey,
+            R.drawable.wallpaper_green,
+            R.drawable.wallpaper_pink,
+    };
+
+    private Gallery mGallery;
+    private ImageView mImageView;
+    private boolean mIsWallpaperSet;
+
+    private BitmapFactory.Options mOptions;
+    private Bitmap mBitmap;
+
+    private ArrayList<Integer> mThumbs;
+    private ArrayList<Integer> mImages;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        findWallpapers();
+
+        setContentView(R.layout.wallpaper_chooser);
+
+        mOptions = new BitmapFactory.Options();
+        mOptions.inDither = false;
+        mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
+
+        mGallery = (Gallery) findViewById(R.id.gallery);
+        mGallery.setAdapter(new ImageAdapter(this));
+        mGallery.setOnItemSelectedListener(this);
+        mGallery.setCallbackDuringFling(false);
+
+        Button b = (Button) findViewById(R.id.set);
+        b.setOnClickListener(this);
+
+        mImageView = (ImageView) findViewById(R.id.wallpaper);
+    }
+
+    private void findWallpapers() {
+        mThumbs = new ArrayList<Integer>(THUMB_IDS.length + 4);
+        Collections.addAll(mThumbs, THUMB_IDS);
+
+        mImages = new ArrayList<Integer>(IMAGE_IDS.length + 4);
+        Collections.addAll(mImages, IMAGE_IDS);
+
+        final Resources resources = getResources();
+        final String[] extras = resources.getStringArray(R.array.extra_wallpapers);
+        final String packageName = getApplication().getPackageName();
+
+        for (String extra : extras) {
+            int res = resources.getIdentifier(extra, "drawable", packageName);
+            if (res != 0) {
+                final int thumbRes = resources.getIdentifier(extra + "_small",
+                        "drawable", packageName);
+
+                if (thumbRes != 0) {
+                    mThumbs.add(thumbRes);
+                    mImages.add(res);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mIsWallpaperSet = false;
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        final ImageView view = mImageView;
+        Bitmap b = BitmapFactory.decodeResource(getResources(), mImages.get(position), mOptions);
+        view.setImageBitmap(b);
+
+        // Help the GC
+        if (mBitmap != null) {
+            mBitmap.recycle();
+        }
+        mBitmap = b;
+
+        final Drawable drawable = view.getDrawable();
+        drawable.setFilterBitmap(true);
+        drawable.setDither(true);
+    }
+
+    /*
+     * When using touch if you tap an image it triggers both the onItemClick and
+     * the onTouchEvent causing the wallpaper to be set twice. Ensure we only
+     * set the wallpaper once.
+     */
+    private void selectWallpaper(int position) {
+        if (mIsWallpaperSet) {
+            return;
+        }
+
+        mIsWallpaperSet = true;
+        try {
+            InputStream stream = getResources().openRawResource(mImages.get(position));
+            setWallpaper(stream);
+            setResult(RESULT_OK);
+            finish();
+        } catch (IOException e) {
+            Log.e(Launcher.LOG_TAG, "Failed to set wallpaper: " + e);
+        }
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+
+    private class ImageAdapter extends BaseAdapter {
+        private LayoutInflater mLayoutInflater;
+
+        ImageAdapter(WallpaperChooser context) {
+            mLayoutInflater = context.getLayoutInflater();
+        }
+
+        public int getCount() {
+            return mThumbs.size();
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView image;
+
+            if (convertView == null) {
+                image = (ImageView) mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
+            } else {
+                image = (ImageView) convertView;
+            }
+
+            image.setImageResource(mThumbs.get(position));
+            image.getDrawable().setDither(true);
+            return image;
+        }
+    }
+
+    public void onClick(View v) {
+        selectWallpaper(mGallery.getSelectedItemPosition());
+    }
+}
diff --git a/src/com/android/launcher/Widget.java b/src/com/android/launcher/Widget.java
new file mode 100644
index 0000000..4f246cc
--- /dev/null
+++ b/src/com/android/launcher/Widget.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.ContentValues;
+import android.graphics.Bitmap;
+
+/**
+ * Represents one instance of a Launcher widget, such as search.
+ */
+class Widget extends ItemInfo {
+    int layoutResource;
+
+    static Widget makeSearch() {
+        Widget w = new Widget();
+        w.itemType = LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH;
+        w.spanX = 4;
+        w.spanY = 1;
+        w.layoutResource = R.layout.widget_search;
+        return w;
+    }
+}
diff --git a/src/com/android/launcher/Workspace.java b/src/com/android/launcher/Workspace.java
new file mode 100644
index 0000000..d834b8f
--- /dev/null
+++ b/src/com/android/launcher/Workspace.java
@@ -0,0 +1,1256 @@
+/*
+ * Copyright (C) 2008 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.launcher;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.Scroller;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+
+/**
+ * The workspace is a wide area with a wallpaper and a finite number of screens. Each
+ * screen contains a number of icons, folders or widgets the user can interact with.
+ * A workspace is meant to be used with a fixed width only.
+ */
+public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller {
+    private static final int INVALID_SCREEN = -1;
+
+    /**
+     * The velocity at which a fling gesture will cause us to snap to the next screen
+     */
+    private static final int SNAP_VELOCITY = 1000;
+
+    private int mDefaultScreen;
+
+    private Paint mPaint;
+    private Bitmap mWallpaper;
+
+    private int mWallpaperWidth;
+    private int mWallpaperHeight;
+    private float mWallpaperOffset;
+    private boolean mWallpaperLoaded;
+
+    private boolean mFirstLayout = true;
+
+    private int mCurrentScreen;
+    private int mNextScreen = INVALID_SCREEN;
+    private Scroller mScroller;
+    private VelocityTracker mVelocityTracker;
+
+    /**
+     * CellInfo for the cell that is currently being dragged
+     */
+    private CellLayout.CellInfo mDragInfo;
+
+    private float mLastMotionX;
+    private float mLastMotionY;
+
+    private final static int TOUCH_STATE_REST = 0;
+    private final static int TOUCH_STATE_SCROLLING = 1;
+
+    private int mTouchState = TOUCH_STATE_REST;
+
+    private OnLongClickListener mLongClickListener;
+
+    private Launcher mLauncher;
+    private DragController mDragger;
+
+    private int[] mTempCell = new int[2];
+
+    private boolean mAllowLongPress;
+    private boolean mLocked;
+
+    private int mTouchSlop;
+
+    final Rect mDrawerBounds = new Rect();
+    final Rect mClipBounds = new Rect();
+
+    /**
+     * Used to inflate the Workspace from XML.
+     *
+     * @param context The application's context.
+     * @param attrs The attribtues set containing the Workspace's customization values.
+     */
+    public Workspace(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    /**
+     * Used to inflate the Workspace from XML.
+     *
+     * @param context The application's context.
+     * @param attrs The attribtues set containing the Workspace's customization values.
+     * @param defStyle Unused.
+     */
+    public Workspace(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Workspace, defStyle, 0);
+        mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 1);
+        a.recycle();
+
+        initWorkspace();
+    }
+
+    /**
+     * Initializes various states for this workspace.
+     */
+    private void initWorkspace() {
+        mScroller = new Scroller(getContext());
+        mCurrentScreen = mDefaultScreen;
+        Launcher.setScreen(mCurrentScreen);
+
+        mPaint = new Paint();
+        mPaint.setDither(false);
+
+        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+    }
+
+    /**
+     * Set the background's wallpaper.
+     */
+    void loadWallpaper(Bitmap bitmap) {
+        mWallpaper = bitmap;
+        mWallpaperLoaded = true;
+        requestLayout();
+        invalidate();
+    }
+
+    @Override
+    public void addView(View child, int index, LayoutParams params) {
+        if (!(child instanceof CellLayout)) {
+            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
+        }
+        super.addView(child, index, params);
+    }
+
+    @Override
+    public void addView(View child) {
+        if (!(child instanceof CellLayout)) {
+            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
+        }
+        super.addView(child);
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        if (!(child instanceof CellLayout)) {
+            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
+        }
+        super.addView(child, index);
+    }
+
+    @Override
+    public void addView(View child, int width, int height) {
+        if (!(child instanceof CellLayout)) {
+            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
+        }
+        super.addView(child, width, height);
+    }
+
+    @Override
+    public void addView(View child, LayoutParams params) {
+        if (!(child instanceof CellLayout)) {
+            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
+        }
+        super.addView(child, params);
+    }
+
+    /**
+     * @return The open folder on the current screen, or null if there is none
+     */
+    Folder getOpenFolder() {
+        CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);
+        int count = currentScreen.getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = currentScreen.getChildAt(i);
+            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+            if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
+                return (Folder) child;
+            }
+        }
+        return null;
+    }
+
+    ArrayList<Folder> getOpenFolders() {
+        final int screens = getChildCount();
+        ArrayList<Folder> folders = new ArrayList<Folder>(screens);
+
+        for (int screen = 0; screen < screens; screen++) {
+            CellLayout currentScreen = (CellLayout) getChildAt(screen);
+            int count = currentScreen.getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = currentScreen.getChildAt(i);
+                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+                if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
+                    folders.add((Folder) child);
+                    break;
+                }
+            }
+        }
+
+        return folders;
+    }
+
+    boolean isDefaultScreenShowing() {
+        return mCurrentScreen == mDefaultScreen;
+    }
+
+    /**
+     * Returns the index of the currently displayed screen.
+     *
+     * @return The index of the currently displayed screen.
+     */
+    int getCurrentScreen() {
+        return mCurrentScreen;
+    }
+
+    /**
+     * Computes a bounding rectangle for a range of cells
+     *
+     * @param cellX X coordinate of upper left corner expressed as a cell position
+     * @param cellY Y coordinate of upper left corner expressed as a cell position
+     * @param cellHSpan Width in cells
+     * @param cellVSpan Height in cells
+     * @param rect Rectnagle into which to put the results
+     */
+    public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF rect) {
+        ((CellLayout)getChildAt(mCurrentScreen)).cellToRect(cellX, cellY,
+                cellHSpan, cellVSpan, rect);
+    }
+
+    /**
+     * Sets the current screen.
+     *
+     * @param currentScreen
+     */
+    void setCurrentScreen(int currentScreen) {
+        mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));
+        scrollTo(mCurrentScreen * getWidth(), 0);
+        invalidate();
+    }
+
+    /**
+     * Shows the default screen (defined by the firstScreen attribute in XML.)
+     */
+    void showDefaultScreen() {
+        setCurrentScreen(mDefaultScreen);
+    }
+
+    /**
+     * Adds the specified child in the current screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param x The X position of the child in the screen's grid.
+     * @param y The Y position of the child in the screen's grid.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     */
+    void addInCurrentScreen(View child, int x, int y, int spanX, int spanY) {
+        addInScreen(child, mCurrentScreen, x, y, spanX, spanY, false);
+    }
+
+    /**
+     * Adds the specified child in the current screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param x The X position of the child in the screen's grid.
+     * @param y The Y position of the child in the screen's grid.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     * @param insert When true, the child is inserted at the beginning of the children list.
+     */
+    void addInCurrentScreen(View child, int x, int y, int spanX, int spanY, boolean insert) {
+        addInScreen(child, mCurrentScreen, x, y, spanX, spanY, insert);
+    }
+
+    /**
+     * Adds the specified child in the specified screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param screen The screen in which to add the child.
+     * @param x The X position of the child in the screen's grid.
+     * @param y The Y position of the child in the screen's grid.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     */
+    void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) {
+        addInScreen(child, screen, x, y, spanX, spanY, false);
+    }
+
+    /**
+     * Adds the specified child in the specified screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param screen The screen in which to add the child.
+     * @param x The X position of the child in the screen's grid.
+     * @param y The Y position of the child in the screen's grid.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     * @param insert When true, the child is inserted at the beginning of the children list.
+     */
+    void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) {
+        if (screen < 0 || screen >= getChildCount()) {
+            throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount());
+        }
+
+        final CellLayout group = (CellLayout) getChildAt(screen);
+        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+        if (lp == null) {
+            lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
+        } else {
+            lp.cellX = x;
+            lp.cellY = y;
+            lp.cellHSpan = spanX;
+            lp.cellVSpan = spanY;
+        }
+        group.addView(child, insert ? 0 : -1, lp);
+        if (!(child instanceof Folder)) {
+            child.setOnLongClickListener(mLongClickListener);
+        }
+    }
+
+    void addWidget(View view, Widget widget) {
+        addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX,
+                widget.spanY, false);
+    }
+
+    void addWidget(View view, Widget widget, boolean insert) {
+        addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX,
+                widget.spanY, insert);
+    }
+
+    CellLayout.CellInfo findAllVacantCells(boolean[] occupied) {
+        CellLayout group = (CellLayout) getChildAt(mCurrentScreen);
+        if (group != null) {
+            return group.findAllVacantCells(occupied);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the coordinate of a vacant cell for the current screen.
+     */
+    boolean getVacantCell(int[] vacant, int spanX, int spanY) {
+        CellLayout group = (CellLayout) getChildAt(mCurrentScreen);
+        if (group != null) {
+            return group.getVacantCell(vacant, spanX, spanY);
+        }
+        return false;
+    }
+
+    /**
+     * Adds the specified child in the current screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     */
+    void fitInCurrentScreen(View child, int spanX, int spanY) {
+        fitInScreen(child, mCurrentScreen, spanX, spanY);
+    }
+
+    /**
+     * Adds the specified child in the specified screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param screen The screen in which to add the child.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     */
+    void fitInScreen(View child, int screen, int spanX, int spanY) {
+        if (screen < 0 || screen >= getChildCount()) {
+            throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount());
+        }
+
+        final CellLayout group = (CellLayout) getChildAt(screen);
+        boolean vacant = group.getVacantCell(mTempCell, spanX, spanY);
+        if (vacant) {
+            group.addView(child,
+                    new CellLayout.LayoutParams(mTempCell[0], mTempCell[1], spanX, spanY));
+            child.setOnLongClickListener(mLongClickListener);
+            if (!(child instanceof Folder)) {
+                child.setOnLongClickListener(mLongClickListener);
+            }
+        }
+    }
+
+    /**
+     * Registers the specified listener on each screen contained in this workspace.
+     *
+     * @param l The listener used to respond to long clicks.
+     */
+    @Override
+    public void setOnLongClickListener(OnLongClickListener l) {
+        mLongClickListener = l;
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            getChildAt(i).setOnLongClickListener(l);
+        }
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mScroller.computeScrollOffset()) {
+            mScrollX = mScroller.getCurrX();
+            mScrollY = mScroller.getCurrY();
+            postInvalidate();
+        } else if (mNextScreen != INVALID_SCREEN) {
+            mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
+            Launcher.setScreen(mCurrentScreen);
+            mNextScreen = INVALID_SCREEN;
+            clearChildrenCache();
+        }
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        // If the all apps drawer is open and the drawing region for the workspace
+        // is contained within the drawer's bounds, we skip the drawing. This requires
+        // the drawer to be fully opaque.
+        if (mLauncher.isDrawerUp()) {
+            final Rect clipBounds = mClipBounds;
+            canvas.getClipBounds(clipBounds);
+            clipBounds.offset(-mScrollX, -mScrollY);
+            if (mDrawerBounds.contains(clipBounds)) {
+                return;
+            }
+        }
+
+        float x = mScrollX * mWallpaperOffset;
+        if (x + mWallpaperWidth < mRight - mLeft) {
+            x = mRight - mLeft - mWallpaperWidth;
+        }
+
+        canvas.drawBitmap(mWallpaper, x, (mBottom - mTop - mWallpaperHeight) / 2, mPaint);
+
+        // ViewGroup.dispatchDraw() supports many features we don't need:
+        // clip to padding, layout animation, animation listener, disappearing
+        // children, etc. The following implementation attempts to fast-track
+        // the drawing dispatch by drawing only what we know needs to be drawn.
+
+        boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
+        // If we are not scrolling or flinging, draw only the current screen
+        if (fastDraw) {
+            drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
+        } else {
+            final long drawingTime = getDrawingTime();
+            // If we are flinging, draw only the current screen and the target screen
+            if (mNextScreen >= 0 && mNextScreen < getChildCount() &&
+                    Math.abs(mCurrentScreen - mNextScreen) == 1) {
+                drawChild(canvas, getChildAt(mCurrentScreen), drawingTime);
+                drawChild(canvas, getChildAt(mNextScreen), drawingTime);
+            } else {
+                // If we are scrolling, draw all of our children
+                final int count = getChildCount();
+                for (int i = 0; i < count; i++) {
+                    drawChild(canvas, getChildAt(i), drawingTime);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        if (widthMode != MeasureSpec.EXACTLY) {
+            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
+        }
+
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        if (heightMode != MeasureSpec.EXACTLY) {
+            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
+        }
+
+        // The children are given the same width and height as the workspace
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        if (mWallpaperLoaded) {
+            mWallpaperLoaded = false;
+            mWallpaper = Utilities.centerToFit(mWallpaper, width,
+                    MeasureSpec.getSize(heightMeasureSpec), getContext());
+            mWallpaperWidth = mWallpaper.getWidth();
+            mWallpaperHeight = mWallpaper.getHeight();
+        }
+
+        final int wallpaperWidth = mWallpaperWidth;
+        mWallpaperOffset = wallpaperWidth > width ? (count * width - wallpaperWidth) /
+                ((count - 1) * (float) width) : 1.0f;
+
+        if (mFirstLayout) {
+            scrollTo(mCurrentScreen * width, 0);
+            mFirstLayout = false;
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        int childLeft = 0;
+
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE) {
+                final int childWidth = child.getMeasuredWidth();
+                child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
+                childLeft += childWidth;
+            }
+        }
+    }
+
+    @Override
+    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
+        int screen = indexOfChild(child);
+        if (screen != mCurrentScreen || !mScroller.isFinished()) {
+            if (!mLauncher.isWorkspaceLocked()) {
+                snapToScreen(screen);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        if (mLauncher.isDrawerDown()) {
+            final Folder openFolder = getOpenFolder();
+            if (openFolder != null) {
+                return openFolder.requestFocus(direction, previouslyFocusedRect);
+            } else {
+                int focusableScreen;
+                if (mNextScreen != INVALID_SCREEN) {
+                    focusableScreen = mNextScreen;
+                } else {
+                    focusableScreen = mCurrentScreen;
+                }
+                getChildAt(focusableScreen).requestFocus(direction, previouslyFocusedRect);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean dispatchUnhandledMove(View focused, int direction) {
+        if (direction == View.FOCUS_LEFT) {
+            if (getCurrentScreen() > 0) {
+                snapToScreen(getCurrentScreen() - 1);
+                return true;
+            }
+        } else if (direction == View.FOCUS_RIGHT) {
+            if (getCurrentScreen() < getChildCount() - 1) {
+                snapToScreen(getCurrentScreen() + 1);
+                return true;
+            }
+        }
+        return super.dispatchUnhandledMove(focused, direction);
+    }
+
+    @Override
+    public void addFocusables(ArrayList<View> views, int direction) {
+        if (mLauncher.isDrawerDown()) {
+            final Folder openFolder = getOpenFolder();
+            if (openFolder == null) {
+                getChildAt(mCurrentScreen).addFocusables(views, direction);
+                if (direction == View.FOCUS_LEFT) {
+                    if (mCurrentScreen > 0) {
+                        getChildAt(mCurrentScreen - 1).addFocusables(views, direction);
+                    }
+                } else if (direction == View.FOCUS_RIGHT){
+                    if (mCurrentScreen < getChildCount() - 1) {
+                        getChildAt(mCurrentScreen + 1).addFocusables(views, direction);
+                    }
+                }
+            } else {
+                openFolder.addFocusables(views, direction);
+            }
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mLocked || !mLauncher.isDrawerDown()) {
+            return true;
+        }
+
+        /*
+         * This method JUST determines whether we want to intercept the motion.
+         * If we return true, onTouchEvent will be called and we do the actual
+         * scrolling there.
+         */
+
+        /*
+         * Shortcut the most recurring case: the user is in the dragging
+         * state and he is moving his finger.  We want to intercept this
+         * motion.
+         */
+        final int action = ev.getAction();
+        if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
+            return true;
+        }
+
+        final float x = ev.getX();
+        final float y = ev.getY();
+
+        switch (action) {
+            case MotionEvent.ACTION_MOVE:
+                /*
+                 * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+                 * whether the user has moved far enough from his original down touch.
+                 */
+
+                /*
+                 * Locally do absolute value. mLastMotionX is set to the y value
+                 * of the down event.
+                 */
+                final int xDiff = (int) Math.abs(x - mLastMotionX);
+                final int yDiff = (int) Math.abs(y - mLastMotionY);
+
+                final int touchSlop = mTouchSlop;
+                boolean xMoved = xDiff > touchSlop;
+                boolean yMoved = yDiff > touchSlop;
+                
+                if (xMoved || yMoved) {
+                    
+                    if (xMoved) {
+                        // Scroll if the user moved far enough along the X axis
+                        mTouchState = TOUCH_STATE_SCROLLING;
+                        enableChildrenCache();
+                    }
+                    // Either way, cancel any pending longpress
+                    if (mAllowLongPress) {
+                        mAllowLongPress = false;
+                        // Try canceling the long press. It could also have been scheduled
+                        // by a distant descendant, so use the mAllowLongPress flag to block
+                        // everything
+                        final View currentScreen = getChildAt(mCurrentScreen);
+                        currentScreen.cancelLongPress();
+                    }
+                }
+                break;
+
+            case MotionEvent.ACTION_DOWN:
+                // Remember location of down touch
+                mLastMotionX = x;
+                mLastMotionY = y;
+                mAllowLongPress = true;
+
+                /*
+                 * If being flinged and user touches the screen, initiate drag;
+                 * otherwise don't.  mScroller.isFinished should be false when
+                 * being flinged.
+                 */
+                mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                // Release the drag
+                clearChildrenCache();
+                mTouchState = TOUCH_STATE_REST;
+                mAllowLongPress = false;
+                break;
+        }
+
+        /*
+         * The only time we want to intercept motion events is if we are in the
+         * drag mode.
+         */
+        return mTouchState != TOUCH_STATE_REST;
+    }
+
+    void enableChildrenCache() {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final CellLayout layout = (CellLayout) getChildAt(i);
+            layout.setChildrenDrawnWithCacheEnabled(true);
+            layout.setChildrenDrawingCacheEnabled(true);
+        }
+    }
+
+    void clearChildrenCache() {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final CellLayout layout = (CellLayout) getChildAt(i);
+            layout.setChildrenDrawnWithCacheEnabled(false);
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (mLocked || !mLauncher.isDrawerDown()) {
+            return true;
+        }
+
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getAction();
+        final float x = ev.getX();
+
+        switch (action) {
+        case MotionEvent.ACTION_DOWN:
+            /*
+             * If being flinged and user touches, stop the fling. isFinished
+             * will be false if being flinged.
+             */
+            if (!mScroller.isFinished()) {
+                mScroller.abortAnimation();
+            }
+
+            // Remember where the motion event started
+            mLastMotionX = x;
+            break;
+        case MotionEvent.ACTION_MOVE:
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                // Scroll to follow the motion event
+                final int deltaX = (int) (mLastMotionX - x);
+                mLastMotionX = x;
+
+                if (deltaX < 0) {
+                    if (mScrollX > 0) {
+                        scrollBy(Math.max(-mScrollX, deltaX), 0);
+                    }
+                } else if (deltaX > 0) {
+                    final int availableToScroll = getChildAt(getChildCount() - 1).getRight() -
+                            mScrollX - getWidth();
+                    if (availableToScroll > 0) {
+                        scrollBy(Math.min(availableToScroll, deltaX), 0);
+                    }
+                }
+            }
+            break;
+        case MotionEvent.ACTION_UP:
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                final VelocityTracker velocityTracker = mVelocityTracker;
+                velocityTracker.computeCurrentVelocity(1000);
+                int velocityX = (int) velocityTracker.getXVelocity();
+
+                if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
+                    // Fling hard enough to move left
+                    snapToScreen(mCurrentScreen - 1);
+                } else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {
+                    // Fling hard enough to move right
+                    snapToScreen(mCurrentScreen + 1);
+                } else {
+                    snapToDestination();
+                }
+
+                if (mVelocityTracker != null) {
+                    mVelocityTracker.recycle();
+                    mVelocityTracker = null;
+                }
+            }
+            mTouchState = TOUCH_STATE_REST;
+            break;
+        case MotionEvent.ACTION_CANCEL:
+            mTouchState = TOUCH_STATE_REST;
+        }
+
+        return true;
+    }
+
+    private void snapToDestination() {
+        final int screenWidth = getWidth();
+        final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;
+
+        snapToScreen(whichScreen);
+    }
+
+    void snapToScreen(int whichScreen) {
+        enableChildrenCache();
+
+        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
+        boolean changingScreens = whichScreen != mCurrentScreen;
+        
+        mNextScreen = whichScreen;
+        
+        View focusedChild = getFocusedChild();
+        if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {
+            focusedChild.clearFocus();
+        }
+        
+        final int newX = whichScreen * getWidth();
+        final int delta = newX - mScrollX;
+        mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 2);
+        invalidate();
+    }
+
+    void startDrag(CellLayout.CellInfo cellInfo) {
+        View child = cellInfo.cell;
+        
+        // Make sure the drag was started by a long press as opposed to a long click.
+        // Note that Search takes focus when clicked rather than entering touch mode
+        if (!child.isInTouchMode() && !(child instanceof Search)) {
+            return;
+        }
+        
+        mDragInfo = cellInfo;
+        mDragInfo.screen = mCurrentScreen;
+        
+        CellLayout current = ((CellLayout) getChildAt(mCurrentScreen));
+
+        current.onDragChild(child);
+        mDragger.startDrag(child, this, child.getTag(), DragController.DRAG_ACTION_MOVE);
+        invalidate();
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        final SavedState state = new SavedState(super.onSaveInstanceState());
+        state.currentScreen = mCurrentScreen;
+        return state;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState savedState = (SavedState) state;
+        super.onRestoreInstanceState(savedState.getSuperState());
+        if (savedState.currentScreen != -1) {
+            mCurrentScreen = savedState.currentScreen;
+            Launcher.setScreen(mCurrentScreen);
+        }
+    }
+
+    void addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo) {
+        addApplicationShortcut(info, cellInfo, false);
+    }
+
+    void addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo,
+            boolean insertAtFirst) {
+        final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen);
+        final int[] result = new int[2];
+
+        layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result);
+        onDropExternal(result[0], result[1], info, layout, insertAtFirst);
+    }
+
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        final CellLayout cellLayout = (CellLayout) getChildAt(mCurrentScreen);
+        if (source != this) {
+            onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout);
+        } else {
+            // Move internally
+            if (mDragInfo != null) {
+                final View cell = mDragInfo.cell;
+                if (mCurrentScreen != mDragInfo.screen) {
+                    final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
+                    originalCellLayout.removeView(cell);
+                    cellLayout.addView(cell);
+                }
+                cellLayout.onDropChild(cell, x - xOffset, y - yOffset);
+
+                final ItemInfo info = (ItemInfo)cell.getTag();
+                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
+                LauncherModel.moveItemInDatabase(mLauncher, info,
+                        LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
+            }
+        }
+    }
+
+    public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+    }
+
+    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+    }
+
+    public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+    }
+
+    private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout) {
+        onDropExternal(x, y, dragInfo, cellLayout, false);
+    }
+    
+    private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout,
+            boolean insertAtFirst) {
+        // Drag from somewhere else
+        ItemInfo info = (ItemInfo) dragInfo;
+
+        View view;
+
+        switch (info.itemType) {
+        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+            if (info.container == NO_ID) {
+                // Came from all apps -- make a copy
+                info = new ApplicationInfo((ApplicationInfo) info);
+            }
+            view = mLauncher.createShortcut(R.layout.application, cellLayout,
+                    (ApplicationInfo) info);
+            break;
+        case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+            view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
+                    (ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info));
+            break;
+        default:
+            throw new IllegalStateException("Unknown item type: " + info.itemType);
+        }
+
+        cellLayout.addView(view, insertAtFirst ? 0 : -1);
+        view.setOnLongClickListener(mLongClickListener);
+        cellLayout.onDropChild(view, x, y);
+        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
+
+        final LauncherModel model = Launcher.getModel();
+        model.addDesktopItem(info);
+        LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
+                LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
+    }
+
+    public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+            Object dragInfo) {
+
+        final CellLayout.CellInfo cellInfo = mDragInfo;
+        int cellHSpan = cellInfo == null ? 1 : cellInfo.spanX;
+        int cellVSpan = cellInfo == null ? 1 : cellInfo.spanY;
+
+        return ((CellLayout) getChildAt(mCurrentScreen)).acceptChildDrop(x - xOffset, y - yOffset,
+                cellHSpan, cellVSpan, cellInfo == null ? null : cellInfo.cell);
+    }
+
+    void setLauncher(Launcher launcher) {
+        mLauncher = launcher;
+    }
+
+    public void setDragger(DragController dragger) {
+        mDragger = dragger;
+    }
+
+    public void onDropCompleted(View target, boolean success) {
+        if (success){
+            if (target != this && mDragInfo != null) {
+                final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
+                cellLayout.removeView(mDragInfo.cell);
+                final Object tag = mDragInfo.cell.getTag();
+                Launcher.getModel().removeDesktopItem((ItemInfo) tag);
+            }
+        } else {
+            if (mDragInfo != null) {
+                final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
+                cellLayout.onDropAborted(mDragInfo.cell);
+            }
+        }
+
+        mDragInfo = null;
+    }
+
+    public void scrollLeft() {
+        if (mNextScreen == INVALID_SCREEN && mCurrentScreen > 0 && mScroller.isFinished()) {
+            snapToScreen(mCurrentScreen - 1);
+        }
+    }
+
+    public void scrollRight() {
+        if (mNextScreen == INVALID_SCREEN && mCurrentScreen < getChildCount() -1 &&
+                mScroller.isFinished()) {
+            snapToScreen(mCurrentScreen + 1);
+        }
+    }
+
+    public int getScreenForView(View v) {
+        int result = -1;
+        if (v != null) {
+            ViewParent vp = v.getParent();
+            int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                if (vp == getChildAt(i)) {
+                    return i;
+                }
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Find a search widget on the given screen
+     */
+    private Search findSearchWidget(CellLayout screen) {
+        final int count = screen.getChildCount();
+        for (int i = 0; i < count; i++) {
+            View v = screen.getChildAt(i);
+            if (v instanceof Search) {
+                return (Search) v;
+            }
+        }
+        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 
+     */
+    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 Folder getFolderForTag(Object tag) {
+        int screenCount = getChildCount();
+        for (int screen = 0; screen < screenCount; screen++) {
+            CellLayout currentScreen = ((CellLayout) getChildAt(screen));
+            int count = currentScreen.getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = currentScreen.getChildAt(i);
+                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+                if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
+                    Folder f = (Folder) child;
+                    if (f.getInfo() == tag) {
+                        return f;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public View getViewForTag(Object tag) {
+        int screenCount = getChildCount();
+        for (int screen = 0; screen < screenCount; screen++) {
+            CellLayout currentScreen = ((CellLayout) getChildAt(screen));
+            int count = currentScreen.getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = currentScreen.getChildAt(i);
+                if (child.getTag() == tag) {
+                    return child;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Unlocks the SlidingDrawer so that touch events are processed.
+     *
+     * @see #lock()
+     */
+    public void unlock() {
+        mLocked = false;
+    }
+
+    /**
+     * Locks the SlidingDrawer so that touch events are ignores.
+     *
+     * @see #unlock()
+     */
+    public void lock() {
+        mLocked = true;
+    }
+    
+    /**
+     * @return True is long presses are still allowed for the current touch
+     */
+    public boolean allowLongPress() {
+        return mAllowLongPress;
+    }
+
+    void removeShortcutsForPackage(String packageName) {
+        final ArrayList<View> childrenToRemove = new ArrayList<View>();
+        final LauncherModel model = Launcher.getModel();
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final CellLayout layout = (CellLayout) getChildAt(i);
+            int childCount = layout.getChildCount();
+            childrenToRemove.clear();
+            for (int j = 0; j < childCount; j++) {
+                final View view = layout.getChildAt(j);
+                Object tag = view.getTag();
+                if (tag instanceof ApplicationInfo) {
+                    ApplicationInfo info = (ApplicationInfo) tag;
+                    // We need to check for ACTION_MAIN otherwise getComponent() might
+                    // return null for some shortcuts (for instance, for shortcuts to
+                    // web pages.)
+                    final Intent intent = info.intent;
+                    final ComponentName name = intent.getComponent();
+                    if (Intent.ACTION_MAIN.equals(intent.getAction()) &&
+                            name != null && packageName.equals(name.getPackageName())) {
+                        model.removeDesktopItem(info);
+                        LauncherModel.deleteItemFromDatabase(mLauncher, info);
+                        childrenToRemove.add(view);
+                    }
+                }
+            }
+            childCount = childrenToRemove.size();
+            for (int j = 0; j < childCount; j++) {
+                layout.removeViewInLayout(childrenToRemove.get(j));
+            }
+            if (childCount > 0) {
+                layout.requestLayout();
+                layout.invalidate();
+            }
+        }
+    }
+    
+    // TODO: remove gadgets when gadgetmanager tells us they're gone
+//    void removeGadgetsForProvider() {
+//    }
+
+    void moveToDefaultScreen() {
+        snapToScreen(mDefaultScreen);
+        getChildAt(mDefaultScreen).requestFocus();
+    }
+
+    public static class SavedState extends BaseSavedState {
+        int currentScreen = -1;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            currentScreen = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeInt(currentScreen);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+}
