diff --git a/src/com/android/launcher/AddAdapter.java b/src/com/android/launcher/AddAdapter.java
new file mode 100644
index 0000000..49422c6
--- /dev/null
+++ b/src/com/android/launcher/AddAdapter.java
@@ -0,0 +1,428 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.BaseExpandableListAdapter;
+import android.graphics.drawable.Drawable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Shows a list of all the items that can be added to the workspace.
+ */
+public final class AddAdapter extends BaseExpandableListAdapter {
+    private static final int GROUP_APPLICATIONS = 0;
+    private static final int GROUP_SHORTCUTS = 1;
+    private static final int GROUP_WIDGETS = 2;
+    private static final int GROUP_WALLPAPERS = 3;
+
+    private final Intent mCreateShortcutIntent;
+    private Intent mSetWallpaperIntent;
+    private final LayoutInflater mInflater;
+    private Launcher mLauncher;
+    private Group[] mGroups;
+
+    /**
+     * Abstract class representing one thing that can be added
+     */
+    public abstract class AddAction implements Runnable {
+        private final Context mContext;
+
+        AddAction(Context context) {
+            mContext = context;
+        }
+
+        Drawable getIcon(int resource) {
+            return mContext.getResources().getDrawable(resource);
+        }
+
+        public abstract void bindView(View v);
+    }
+
+    /**
+     * Class representing an action that will create set the wallpaper.
+     */
+    public class SetWallpaperAction extends CreateShortcutAction {
+        SetWallpaperAction(Context context, ResolveInfo info) {
+            super(context, info);
+        }
+
+        public void run() {
+            Intent intent = new Intent(mSetWallpaperIntent);
+            ActivityInfo activityInfo = mInfo.activityInfo;
+            intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
+                    activityInfo.name));
+            mLauncher.startActivity(intent);
+        }
+    }
+    
+    /**
+     * Class representing an action that will create a specific type
+     * of shortcut
+     */
+    public class CreateShortcutAction extends AddAction {
+        
+        ResolveInfo mInfo;
+        private CharSequence mLabel;
+        private Drawable mIcon;
+
+        CreateShortcutAction(Context context, ResolveInfo info) {
+            super(context);
+            mInfo = info;
+        }
+
+        @Override
+        public void bindView(View view) {
+            ResolveInfo info = mInfo;
+            TextView text = (TextView) view;
+
+            PackageManager pm = mLauncher.getPackageManager();
+
+            if (mLabel == null) {
+                mLabel = info.loadLabel(pm);
+                if (mLabel == null) {
+                    mLabel = info.activityInfo.name;
+                }
+            }
+            if (mIcon == null) {
+                mIcon = info.loadIcon(pm);
+            }
+
+            text.setText(mLabel);
+            text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
+        }
+
+        public void run() {
+            Intent intent = new Intent(mCreateShortcutIntent);
+            ActivityInfo activityInfo = mInfo.activityInfo;
+            intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
+                    activityInfo.name));
+            mLauncher.addShortcut(intent);
+        }
+    }
+    
+    /**
+     * Class representing an action that will add a folder
+     */
+    public class CreateFolderAction extends AddAction {
+        
+        CreateFolderAction(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void bindView(View view) {
+            TextView text = (TextView) view;
+            text.setText(R.string.add_folder);
+            text.setCompoundDrawablesWithIntrinsicBounds(getIcon(R.drawable.ic_launcher_folder),
+                    null, null, null);
+        }
+
+        public void run() {
+            mLauncher.addFolder();
+        }
+    }
+
+    /**
+     * Class representing an action that will add a folder
+     */
+    public class CreateClockAction extends AddAction {
+
+        CreateClockAction(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void bindView(View view) {
+            TextView text = (TextView) view;
+            text.setText(R.string.add_clock);
+            Drawable icon = getIcon(R.drawable.ic_launcher_alarmclock);
+            text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
+        }
+
+        public void run() {
+            mLauncher.addClock();
+        }
+    }
+
+    /**
+     * Class representing an action that will add a PhotoFrame
+     */
+    public class CreatePhotoFrameAction extends AddAction {
+        CreatePhotoFrameAction(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void bindView(View view) {
+            TextView text = (TextView) view;
+            text.setText(R.string.add_photo_frame);
+            Drawable icon = getIcon(R.drawable.ic_launcher_gallery);
+            text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
+        }
+
+        public void run() {
+            mLauncher.getPhotoForPhotoFrame();
+        }
+    }
+
+
+    /**
+     * Class representing an action that will add a Search widget
+     */
+    public class CreateSearchAction extends AddAction {
+        CreateSearchAction(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void bindView(View view) {
+            TextView text = (TextView) view;
+            text.setText(R.string.add_search);
+            Drawable icon = getIcon(R.drawable.ic_search_gadget);
+            text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
+        }
+
+        public void run() {
+            mLauncher.addSearch();
+        }
+    }
+    
+    private class Group {
+        private String mName;
+        private ArrayList<AddAction> mList;
+
+        Group(String name) {
+            mName = name;
+            mList = new ArrayList<AddAction>();
+        }
+
+        void add(AddAction action) {
+            mList.add(action);
+        }
+
+        int size() {
+            return mList.size();
+        }
+
+        String getName() {
+            return mName;
+        }
+
+        void run(int position) {
+            mList.get(position).run();
+        }
+
+        void bindView(int childPosition, View view) {
+            mList.get(childPosition).bindView(view);
+        }
+
+        public Object get(int childPosition) {
+            return mList.get(childPosition);
+        }
+    }
+
+    private class ApplicationsGroup extends Group {
+        private final Launcher mLauncher;
+        private final ArrayList<ApplicationInfo> mApplications;
+
+        ApplicationsGroup(Launcher launcher, String name) {
+            super(name);
+            mLauncher = launcher;
+            mApplications = Launcher.getModel().getApplications();
+        }
+
+        @Override
+        int size() {
+            return mApplications == null ? 0 : mApplications.size();
+        }
+
+        @Override
+        void add(AddAction action) {
+        }
+
+        @Override
+        void run(int position) {
+            final ApplicationInfo info = mApplications.get(position);
+            mLauncher.addApplicationShortcut(info);
+        }
+
+        @Override
+        void bindView(int childPosition, View view) {
+            TextView text = (TextView) view.findViewById(R.id.title);
+
+            final ApplicationInfo info = mApplications.get(childPosition);
+            text.setText(info.title);
+            if (!info.filtered) {
+                info.icon = Utilities.createIconThumbnail(info.icon, mLauncher);
+                info.filtered = true;
+            }
+            text.setCompoundDrawablesWithIntrinsicBounds(info.icon, null, null, null);
+        }
+
+        @Override
+        public Object get(int childPosition) {
+            return mApplications.get(childPosition);
+        }
+    }
+
+    public AddAdapter(Launcher launcher, boolean forFolder) {
+        mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+        mCreateShortcutIntent.setComponent(null);
+
+        mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
+        mSetWallpaperIntent.setComponent(null);
+
+        mLauncher = launcher;
+        mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        mGroups = new Group[forFolder ? 2 : 4];
+        final Group[] groups = mGroups;
+        groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
+                mLauncher.getString(R.string.group_applications));
+        groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts));
+
+        if (!forFolder) {
+            groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
+            groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
+            groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
+            final Group widgets = groups[GROUP_WIDGETS];
+            widgets.add(new CreateClockAction(launcher));
+            widgets.add(new CreatePhotoFrameAction(launcher));
+            widgets.add(new CreateSearchAction(launcher));
+        }
+        
+        PackageManager packageManager = launcher.getPackageManager();
+
+        List<ResolveInfo> list = findTargetsForIntent(mCreateShortcutIntent, packageManager);
+        if (list != null && list.size() > 0) {
+            int count = list.size();
+            final Group shortcuts = groups[GROUP_SHORTCUTS];
+            for (int i = 0; i < count; i++) {
+                ResolveInfo resolveInfo = list.get(i);
+                shortcuts.add(new CreateShortcutAction(launcher, resolveInfo));
+            }
+        }
+
+        list = findTargetsForIntent(mSetWallpaperIntent, packageManager);
+        if (list != null && list.size() > 0) {
+            int count = list.size();
+            final Group shortcuts = groups[GROUP_WALLPAPERS];
+            for (int i = 0; i < count; i++) {
+                ResolveInfo resolveInfo = list.get(i);
+                shortcuts.add(new SetWallpaperAction(launcher, resolveInfo));
+            }
+        }
+    }
+
+    private List<ResolveInfo> findTargetsForIntent(Intent intent, PackageManager packageManager) {
+        List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        if (list != null) {
+            int count = list.size();
+            if (count > 1) {
+                // Only display the first matches that are either of equal
+                // priority or have asked to be default options.
+                ResolveInfo firstInfo = list.get(0);
+                for (int i=1; i<count; i++) {
+                    ResolveInfo resolveInfo = list.get(i);
+                    if (firstInfo.priority != resolveInfo.priority ||
+                        firstInfo.isDefault != resolveInfo.isDefault) {
+                        while (i < count) {
+                            list.remove(i);
+                            count--;
+                        }
+                    }
+                }
+                Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager));
+            }
+        }
+        return list;
+    }
+
+    public int getGroupCount() {
+        return mGroups.length;
+    }
+
+    public int getChildrenCount(int groupPosition) {
+        return mGroups[groupPosition].size();
+    }
+
+    public Object getGroup(int groupPosition) {
+        return mGroups[groupPosition].getName();
+    }
+
+    public Object getChild(int groupPosition, int childPosition) {
+        return mGroups[groupPosition].get(childPosition);
+    }
+
+    public long getGroupId(int groupPosition) {
+        return groupPosition;
+    }
+
+    public long getChildId(int groupPosition, int childPosition) {
+        return (groupPosition << 16) | childPosition;
+    }
+
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    public View getGroupView(int groupPosition, boolean isExpanded,
+            View convertView, ViewGroup parent) {
+        View view;
+        if (convertView == null) {
+            view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false);
+        } else {
+            view = convertView;
+        }
+        ((TextView) view).setText(mGroups[groupPosition].getName());
+        return view;
+    }
+
+    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+            View convertView, ViewGroup parent) {
+        View view;
+        if (convertView == null) {
+            view = mInflater.inflate(R.layout.create_shortcut_list_item, parent, false);
+        } else {
+            view = convertView;
+        }
+        mGroups[groupPosition].bindView(childPosition, view);
+        return view;
+    }
+
+    public boolean isChildSelectable(int groupPosition, int childPosition) {
+        return true;
+    }
+
+    void performAction(int groupPosition, int childPosition) {
+        mGroups[groupPosition].run(childPosition);
+    }
+}
diff --git a/src/com/android/launcher/AllAppsGridView.java b/src/com/android/launcher/AllAppsGridView.java
new file mode 100644
index 0000000..a898c1a
--- /dev/null
+++ b/src/com/android/launcher/AllAppsGridView.java
@@ -0,0 +1,78 @@
+/*
+ * 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.util.AttributeSet;
+import android.view.View;
+
+public class AllAppsGridView extends GridView implements AdapterView.OnItemClickListener,
+        AdapterView.OnItemLongClickListener, DragSource {
+
+    private DragController mDragger;
+    private Launcher mLauncher;
+
+    public AllAppsGridView(Context context) {
+        super(context);
+    }
+
+    public AllAppsGridView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AllAppsGridView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        setOnItemClickListener(this);
+        setOnItemLongClickListener(this);
+    }
+
+    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..ec1c85a
--- /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.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import com.android.internal.provider.Settings;
+
+/**
+ * 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 = Settings.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 Settings.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 = Settings.Favorites.ITEM_TYPE_APPLICATION;
+    }
+
+    @Override
+    void onAddToDatabase(ContentValues values) {
+        super.onAddToDatabase(values);
+
+        String titleStr = title != null ? title.toString() : null;
+        values.put(Settings.Favorites.TITLE, titleStr);
+
+        String uri = intent != null ? intent.toURI() : null;
+        values.put(Settings.Favorites.INTENT, uri);
+
+        if (customIcon) {
+            values.put(Settings.Favorites.ICON_TYPE, Settings.Favorites.ICON_TYPE_BITMAP);
+            Bitmap bitmap = ((BitmapDrawable) icon).getBitmap();
+            writeBitmap(values, bitmap);
+        } else {
+            values.put(Settings.Favorites.ICON_TYPE, Settings.Favorites.ICON_TYPE_RESOURCE);
+            if (iconResource != null) {
+                values.put(Settings.Favorites.ICON_PACKAGE, iconResource.packageName);
+                values.put(Settings.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..730e08e
--- /dev/null
+++ b/src/com/android/launcher/BubbleTextView.java
@@ -0,0 +1,78 @@
+/*
+ * 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.Rect;
+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;
+
+    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);
+
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background));
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        final Layout layout = getLayout();
+        final RectF rect = mRect;
+        final int left = getCompoundPaddingLeft();
+        final int top = getExtendedPaddingTop();
+
+        rect.set(left + layout.getLineLeft(0) - PADDING_H,
+                top + layout.getLineTop(0) - PADDING_V,
+                left + layout.getLineRight(0) + PADDING_H,
+                top + layout.getLineBottom(0) + PADDING_V);
+        canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint);
+
+        super.onDraw(canvas);
+    }
+}
diff --git a/src/com/android/launcher/CellLayout.java b/src/com/android/launcher/CellLayout.java
new file mode 100644
index 0000000..03cf7fc
--- /dev/null
+++ b/src/com/android/launcher/CellLayout.java
@@ -0,0 +1,891 @@
+/*
+ * 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();
+
+    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 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;
+                        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]];
+
+                if (cellInfo.valid) {
+                    findIntersectingVacantCells(cellInfo, cellXY[0], cellXY[1],
+                            xCount, yCount, occupied);
+                }
+            }
+            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;
+            setTag(cellInfo);
+        }
+
+        return false;
+    }
+
+    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.vacantCells = new ArrayList<CellInfo.VacantCell>();
+
+        if (occupied[x][y]) {
+            return;
+        }
+
+        Rect current = new Rect(x, y, x, y);
+        findVacantCell(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 = new CellInfo.VacantCell();
+        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.vacantCells = new ArrayList<CellInfo.VacantCell>();
+        cellInfo.screen = mCellInfo.screen;
+
+        Rect current = new Rect();
+
+        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;
+        if (cellInfo.valid) {
+            int[] xy = new int[2];
+            if (cellInfo.findCellForSpan(xy, 1, 1)) {
+                cellInfo.cellX = xy[0];
+                cellInfo.cellY = xy[1];
+                cellInfo.spanY = 1;
+                cellInfo.spanX = 1;
+            }
+        }
+
+        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);
+    }
+
+    /**
+     * 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 {
+        static final class VacantCell {
+            int cellX;
+            int cellY;
+            int spanX;
+            int spanY;
+
+            @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;
+
+        ArrayList<VacantCell> vacantCells;
+        int maxVacantSpanX;
+        int maxVacantSpanXSpanY;
+        int maxVacantSpanY;
+        int maxVacantSpanYSpanX;
+
+        void findVacantCellsFromOccupied(boolean[] occupied, int xCount, int yCount) {
+            if (cellX < 0 || cellY < 0) {
+                maxVacantSpanX = maxVacantSpanXSpanY = Integer.MIN_VALUE;
+                maxVacantSpanY = maxVacantSpanYSpanX = Integer.MIN_VALUE;
+                vacantCells = new ArrayList<VacantCell>();
+                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);
+        }
+
+        boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
+            if (vacantCells == null) {
+                return false;
+            }
+
+            if (this.spanX >= spanX && this.spanY >= spanY) {
+                cellXY[0] = cellX;
+                cellXY[1] = cellY;
+                return true;
+            }
+
+            final ArrayList<VacantCell> list = vacantCells;
+            final int count = list.size();
+            // 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;
+                    return true;
+                }
+            }
+
+            // 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;
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        @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..ab2b891
--- /dev/null
+++ b/src/com/android/launcher/DeleteZone.java
@@ -0,0 +1,248 @@
+/*
+ * 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 com.android.internal.provider.Settings;
+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 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) {
+        final ItemInfo item = (ItemInfo) dragInfo;
+        // Accept anything except items in the all apps folder
+        return item.container != ItemInfo.NO_ID;
+    }
+
+    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
+        final ItemInfo item = (ItemInfo) dragInfo;
+        final LauncherModel model = Launcher.getModel();
+        if (item.container == Settings.Favorites.CONTAINER_DESKTOP) {
+            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);
+        }
+        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 && item.container != ItemInfo.NO_ID) {
+            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..56140dd
--- /dev/null
+++ b/src/com/android/launcher/DragLayer.java
@@ -0,0 +1,544 @@
+/*
+ * 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.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;
+
+    /**
+     * 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");
+        }
+        
+        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:
+            if (Launcher.sOpenGlEnabled) {
+                mLastMotionX = x;
+                mLastMotionY = y;
+
+                invalidate();
+            } else {
+                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/Folder.java b/src/com/android/launcher/Folder.java
new file mode 100644
index 0000000..1a91eb1
--- /dev/null
+++ b/src/com/android/launcher/Folder.java
@@ -0,0 +1,148 @@
+/*
+ * 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.ArrayAdapter;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.LinearLayout;
+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 GridView 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 = (GridView) 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) {
+        return false;
+    }
+
+    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(ArrayAdapter<ApplicationInfo> 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();
+    }
+}
diff --git a/src/com/android/launcher/FolderIcon.java b/src/com/android/launcher/FolderIcon.java
new file mode 100644
index 0000000..d7c623d
--- /dev/null
+++ b/src/com/android/launcher/FolderIcon.java
@@ -0,0 +1,93 @@
+/*
+ * 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 com.android.internal.provider.Settings;
+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 == Settings.Favorites.ITEM_TYPE_APPLICATION || 
+                itemType == Settings.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..b226b62
--- /dev/null
+++ b/src/com/android/launcher/FolderInfo.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;
+
+
+/**
+ * Represents a folder containing shortcuts or apps.
+ */
+class FolderInfo extends ItemInfo {
+    
+    /**
+     * Whether this folder has been opened
+     */
+    boolean opened;
+}
diff --git a/src/com/android/launcher/InstallShortcutReceiver.java b/src/com/android/launcher/InstallShortcutReceiver.java
new file mode 100644
index 0000000..d99e2b4
--- /dev/null
+++ b/src/com/android/launcher/InstallShortcutReceiver.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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import com.android.internal.provider.Settings;
+
+public class InstallShortcutReceiver extends BroadcastReceiver {
+    private final int[] mCoordinates = new int[2];
+
+    public void onReceive(Context context, Intent data) {
+        int screen = Launcher.getScreen();
+
+        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);
+            }
+        }
+    }
+
+    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(Settings.Favorites.CONTENT_URI,
+            new String[] { "cellX", "cellY", "spanX", "spanY" }, "screen=?",
+            new String[] { String.valueOf(screen) }, null);
+
+        final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
+        final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
+        final int spanXIndex = c.getColumnIndexOrThrow(Settings.Favorites.SPANX);
+        final int spanYIndex = c.getColumnIndexOrThrow(Settings.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..f2ce23d
--- /dev/null
+++ b/src/com/android/launcher/ItemInfo.java
@@ -0,0 +1,130 @@
+/*
+ * 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 com.android.internal.provider.Settings;
+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 Settings.Favorites#ITEM_TYPE_APPLICATION},
+     * {@link Settings.Favorites#ITEM_TYPE_SHORTCUT}, 
+     * {@link Settings.Favorites#ITEM_TYPE_USER_FOLDER},
+     * {@link Settings.Favorites#ITEM_TYPE_WIDGET_CLOCK},
+     * {@link Settings.Favorites#ITEM_TYPE_WIDGET_SEARCH} or
+     * {@link Settings.Favorites#ITEM_TYPE_WIDGET_PHOTO_FRAME},
+     */
+    int itemType;
+    
+    /**
+     * The id of the container that holds this item. For the desktop, this will be 
+     * {@link Settings.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(Settings.Favorites.ITEM_TYPE, itemType);
+        values.put(Settings.Favorites.CONTAINER, container);
+        values.put(Settings.Favorites.SCREEN, screen);
+        values.put(Settings.Favorites.CELLX, cellX);
+        values.put(Settings.Favorites.CELLY, cellY);
+        values.put(Settings.Favorites.SPANX, spanX);
+        values.put(Settings.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(Settings.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..2ae5037
--- /dev/null
+++ b/src/com/android/launcher/Launcher.java
@@ -0,0 +1,1593 @@
+/*
+ * 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.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.hardware.SensorListener;
+import android.hardware.SensorManager;
+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.SystemClock;
+import android.os.SystemProperties;
+import android.provider.Contacts;
+import android.telephony.PhoneNumberUtils;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.method.TextKeyListener;
+import android.util.Config;
+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.widget.EditText;
+import android.widget.ExpandableListView;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.app.IWallpaperService;
+
+import com.android.internal.provider.Settings;
+import com.android.internal.widget.SlidingDrawer;
+
+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";
+
+    private static final boolean PROFILE_STARTUP = false;
+    private static final boolean DEBUG_USER_INTERFACE = false;
+
+    private static final String USE_OPENGL_BY_DEFAULT = "false";
+
+    private static final boolean REMOVE_SHORTCUT_ON_PACKAGE_REMOVE = false;    
+
+    // Type: boolean
+    private static final String PROPERTY_USE_OPENGL = "launcher.opengl";
+    // Type: boolean
+    private static final String PROPERTY_USE_SENSORS = "launcher.sensors";
+
+    private static final boolean USE_OPENGL = true;
+    private static final boolean USE_SENSORS = 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_CHOOSE_PHOTO = 2;
+    private static final int REQUEST_UPDATE_PHOTO = 3;
+
+    static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
+
+    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;    
+
+    // 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;
+
+    // Indicates whether the OpenGL pipeline was enabled, either through
+    // USE_OPENGL_BY_DEFAULT or the system property launcher.opengl
+    static boolean sOpenGlEnabled;
+
+    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 final Handler mHandler = new Handler();
+    private LayoutInflater mInflater;
+
+    private SensorManager mSensorManager;
+    private SensorHandler mSensorHandler;
+
+    private DragLayer mDragLayer;
+    private Workspace mWorkspace;
+
+    private CellLayout.CellInfo mAddItemCellInfo;
+    private CellLayout.CellInfo mMenuAddInfo;
+    private final int[] mCellCoordinates = new int[2];
+    private UserFolderInfo 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;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        dalvik.system.VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
+
+        super.onCreate(savedInstanceState);
+        mInflater = getLayoutInflater();
+
+        if (PROFILE_STARTUP) {
+            android.os.Debug.startMethodTracing("/sdcard/launcher");
+        }
+
+        setWallpaperDimension();
+
+        enableSensors();
+        enableOpenGL();
+
+        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);
+    }
+
+    static int getScreen() {
+        synchronized (sLock) {
+            return sScreen;
+        }
+    }
+
+    static void setScreen(int screen) {
+        synchronized (sLock) {
+            sScreen = screen;
+        }
+    }
+
+    private void startLoaders() {
+        sModel.loadApplications(true, this);
+        sModel.loadUserItems(true, this);
+        mRestoring = false;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        // When MMC/MNC changes, so can applications, so we reload them
+        sModel.loadApplications(false, Launcher.this);
+    }
+
+    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!
+        }
+    }
+
+    private void enableSensors() {
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (USE_SENSORS || "true".equals(SystemProperties.get(PROPERTY_USE_SENSORS, "false"))) {
+            if (Config.LOGD) {
+                Log.d(LOG_TAG, "Launcher activating sensors");
+            }
+            mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
+            mSensorHandler = new SensorHandler();
+        }
+    }
+
+    private void enableOpenGL() {
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (USE_OPENGL && "true".equals(SystemProperties.get(PROPERTY_USE_OPENGL,
+                USE_OPENGL_BY_DEFAULT))) {
+            if (Config.LOGD) {
+                Log.d(LOG_TAG, "Launcher starting in OpenGL");
+            }
+            //requestWindowFeature(Window.FEATURE_OPENGL);
+            //sOpenGlEnabled = true;
+        } else {
+            sOpenGlEnabled = false;
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
+            switch (requestCode) {
+                case REQUEST_CREATE_SHORTCUT:
+                    completeAddShortcut(data, mAddItemCellInfo, !mDesktopLocked);
+                    break;
+                case REQUEST_CHOOSE_PHOTO:
+                    completeAddPhotoFrame(data, mAddItemCellInfo);
+                    break;
+                case REQUEST_UPDATE_PHOTO:
+                    completeUpdatePhotoFrame(data, mAddItemCellInfo);
+                    break;
+            }
+        }
+        mWaitingForResult = false;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (mRestoring) {
+            startLoaders();
+        }
+
+        if (mSensorManager != null) {
+            mSensorManager.registerListener(mSensorHandler, SensorManager.SENSOR_ACCELEROMETER);
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        if (mSensorManager != null) {
+            mSensorManager.unregisterListener(mSensorHandler);
+        }
+
+        super.onStop();
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        boolean handled = super.onKeyUp(keyCode, event);
+        if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+            handled = mWorkspace.snapToSearch();
+        }
+        return handled;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        boolean handled = super.onKeyDown(keyCode, event);
+        if (!handled && 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 ImageView handleIcon = (ImageView) drawer.findViewById(R.id.all_apps);
+        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);
+        if (sOpenGlEnabled) {
+            grid.setScrollingCacheEnabled(false);
+            grid.setFadingEdgeLength(0);
+        }
+
+        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);
+
+        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();
+                }
+            });
+        }
+    }
+
+    /**
+     * 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;
+    }
+
+    void addApplicationShortcut(ApplicationInfo info) {
+        mAddItemCellInfo.screen = mWorkspace.getCurrentScreen();
+        mWorkspace.addApplicationShortcut(info, mAddItemCellInfo);
+    }
+
+    /**
+     * 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();
+        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);
+        }
+    }
+
+    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 BitmapDrawable(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, Settings.Favorites.CONTAINER_DESKTOP,
+                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
+        return info;
+    }
+
+    /**
+     * Add a PhotFrame to the workspace.
+     *
+     * @param data The intent describing the photo.
+     * @param cellInfo The position on screen where to create the shortcut.
+     */
+    private void completeAddPhotoFrame(Intent data, CellLayout.CellInfo cellInfo) {
+        final Bundle extras = data.getExtras();
+        if (extras != null) {
+            Bitmap photo = extras.getParcelable("data");
+
+            Widget info = Widget.makePhotoFrame();
+            info.photo = photo;
+
+            final int[] xy = mCellCoordinates;
+            if (!findSlot(cellInfo, xy, info.spanX, info.spanY)) return;
+
+            LauncherModel.addItemToDatabase(this, info, Settings.Favorites.CONTAINER_DESKTOP,
+                    mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
+
+            if (!mRestoring) {
+                sModel.addDesktopItem(info);
+
+                final PhotoFrame view = (PhotoFrame) mInflater.inflate(info.layoutResource, null);
+                view.setImageBitmap(photo);
+                view.setTag(info);
+
+                mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, info.spanY);
+            } else if (sModel.isDesktopLoaded()) {
+                sModel.addDesktopItem(info);
+            }
+        }
+    }
+
+    /**
+     * Updates a workspace PhotoFrame.
+     *
+     * @param data The intent describing the photo.
+     * @param cellInfo The position on screen of the PhotoFrame to update.
+     */
+    private void completeUpdatePhotoFrame(Intent data, CellLayout.CellInfo cellInfo) {
+        final Bundle extras = data.getExtras();
+        if (extras != null) {
+            Widget info;
+            Bitmap photo = extras.getParcelable("data");
+
+            if (!mRestoring) {
+                final CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
+                final PhotoFrame view = (PhotoFrame) layout.findCell(cellInfo.cellX, cellInfo.cellY,
+                        cellInfo.spanX, cellInfo.spanY, null);
+                view.setImageBitmap(photo);
+                info = (Widget) view.getTag();
+            } else {
+                info = LauncherModel.getPhotoFrameInfo(this, cellInfo.screen,
+                        cellInfo.cellX, cellInfo.cellY);
+            }
+
+            info.photo = photo;
+            LauncherModel.updateItemInDatabase(this, info);
+        }
+    }
+
+    /**
+     * Starts a new Intent to let the user update the PhotoFrame defined by the
+     * specified Widget.
+     *
+     * @param widget The Widget info defining which PhotoFrame to update.
+     */
+    void updatePhotoFrame(Widget widget) {
+        CellLayout.CellInfo info = new CellLayout.CellInfo();
+        info.screen = widget.screen;
+        info.cellX = widget.cellX;
+        info.cellY = widget.cellY;
+        info.spanX = widget.spanX;
+        info.spanY = widget.spanY;
+        mAddItemCellInfo = info;
+
+        startActivityForResult(createPhotoPickIntent(), Launcher.REQUEST_UPDATE_PHOTO);
+    }
+
+    /**
+     * Creates an Intent used to let the user pick a photo for a PhotoFrame.
+     *
+     * @return The Intent to pick a photo suited for a PhotoFrame.
+     */
+    private static Intent createPhotoPickIntent() {
+        // TODO: Move this method to PhotoFrame?
+        // TODO: get these values from constants somewhere
+        // TODO: Adjust the PhotoFrame's image size to avoid on the fly scaling
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
+        intent.setType("image/*");
+        intent.putExtra("crop", "true");
+        intent.putExtra("aspectX", 1);
+        intent.putExtra("aspectY", 1);
+        intent.putExtra("outputX", 192);
+        intent.putExtra("outputY", 192);
+        intent.putExtra("noFaceDetection", true);
+        intent.putExtra("return-data", true);
+        return intent;
+    }
+
+    @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();
+            } else {
+                closeDrawer(false);
+            }
+        }
+    }
+
+    @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();
+
+        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 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(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(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(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()) {
+                    onSearchRequested();
+                }
+                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) {
+            android.util.Log.d(LOG_TAG, packageName);
+            mWorkspace.removeShortcutsForPackage(packageName);
+        }
+    }
+
+    void addShortcut(Intent intent) {
+        startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
+    }
+
+    void addFolder() {
+        UserFolderInfo folderInfo = new UserFolderInfo();
+        folderInfo.title = getText(R.string.folder_name);
+        int cellX = mAddItemCellInfo.cellX;
+        int cellY = mAddItemCellInfo.cellY;
+
+        // Update the model
+        LauncherModel.addItemToDatabase(this, folderInfo, Settings.Favorites.CONTAINER_DESKTOP,
+                mWorkspace.getCurrentScreen(), cellX, cellY, false);
+        sModel.addDesktopItem(folderInfo);
+        sModel.addUserFolder(folderInfo);
+
+        // Create the view
+        FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
+                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()), folderInfo);
+        mWorkspace.addInCurrentScreen(newFolder, cellX, cellY, 1, 1);
+    }
+
+    void getPhotoForPhotoFrame() {
+        startActivityForResult(createPhotoPickIntent(), REQUEST_CHOOSE_PHOTO);
+    }
+
+    void addClock() {
+        final Widget info = Widget.makeClock();
+        addWidget(info);
+    }
+
+    void addSearch() {
+        final Widget info = Widget.makeSearch();
+        addWidget(info);
+    }
+    
+    private void addWidget(final Widget info) {
+        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, Settings.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);
+    }
+
+    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(Settings.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);
+    }
+
+    void onDesktopItemsLoaded() {
+        if (mDestroyed) return;
+
+        bindDesktopItems();
+        mAllAppsGrid.setAdapter(Launcher.getModel().getApplicationsAdapter());
+
+        if (mSavedState != null) {
+            mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
+
+            final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);
+            if (userFolders != null) {
+                for (long folderId : userFolders) {
+                    final UserFolderInfo info = sModel.findFolderById(folderId);
+                    if (info != null) {
+                        openUserFolder(info);
+                    }
+                }
+                final Folder openFolder = mWorkspace.getOpenFolder();
+                if (openFolder != null) {
+                    openFolder.requestFocus();
+                } else {
+                    mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
+                }
+            }
+
+            final boolean allApps = mSavedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
+            if (allApps) {
+                mDrawer.open();
+                mDrawer.requestFocus();
+            }
+
+            mSavedState = null;
+        }
+
+        mDesktopLocked = false;
+        mDrawer.unlock();
+    }
+
+    /**
+     * Refreshes the shortcuts shown on the workspace.
+     */
+    private void bindDesktopItems() {
+        final ArrayList<ItemInfo> shortcuts = sModel.getDesktopItems();
+        if (shortcuts == null) {
+            return;
+        }
+
+        final Workspace workspace = mWorkspace;
+        int count = workspace.getChildCount();
+        for (int i = 0; i < count; i++) {
+            ((ViewGroup) workspace.getChildAt(i)).removeAllViewsInLayout();
+        }
+
+        count = shortcuts.size();
+        for (int i = 0; i < count; i++) {
+            final ItemInfo item = shortcuts.get(i);
+            switch (item.itemType) {
+            case Settings.Favorites.ITEM_TYPE_APPLICATION:
+            case Settings.Favorites.ITEM_TYPE_SHORTCUT:
+                final View shortcut = createShortcut((ApplicationInfo) item);
+                workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
+                        !mDesktopLocked);
+                break;
+            case Settings.Favorites.ITEM_TYPE_USER_FOLDER:
+                final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
+                        (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentScreen()),
+                        ((UserFolderInfo) item));
+                workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
+                        !mDesktopLocked);
+                break;
+            default:
+                final Widget widget = (Widget)item;
+                final View view = createWidget(mInflater, widget);
+                view.setTag(widget);
+                workspace.addWidget(view, widget, !mDesktopLocked);
+            }
+        }
+
+        workspace.requestLayout();
+    }
+
+    private View createWidget(LayoutInflater inflater, Widget widget) {
+        final Workspace workspace = mWorkspace;
+        final int screen = workspace.getCurrentScreen();
+        View v = inflater.inflate(widget.layoutResource,
+                (ViewGroup) workspace.getChildAt(screen), false);
+        if (widget.itemType == Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
+            ((ImageView)v).setImageBitmap(widget.photo);
+        }
+        return v;
+    }
+
+    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 UserFolderInfo) {
+            handleFolderClick((UserFolderInfo) 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();
+        }
+    }
+
+    private void handleFolderClick(FolderInfo folderInfo) {
+        if (!folderInfo.opened) {
+            // Close any open folder
+            closeFolder();
+            // Open the requested folder
+            openUserFolder(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
+                    openUserFolder(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 tag The UserFolderInfo describing the folder to open.
+     */
+    private void openUserFolder(Object tag) {
+        UserFolder openFolder = UserFolder.fromXml(this);
+        openFolder.setDragger(mDragLayer);
+        openFolder.setLauncher(this);
+
+        UserFolderInfo folderInfo = (UserFolderInfo) tag;
+        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 false;
+        }
+
+        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();
+    }
+
+    Workspace getWorkspace() {
+        return mWorkspace;
+    }
+
+    @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(UserFolderInfo 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);
+                } 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);
+                    }
+                }
+            }
+            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 ExpandableListView.OnChildClickListener,
+            DialogInterface.OnCancelListener, ExpandableListView.OnGroupExpandListener {
+        private AddAdapter mAdapter;
+        private ExpandableListView mList;
+
+        Dialog createDialog() {
+            mWaitingForResult = true;
+            mAdapter = new AddAdapter(Launcher.this, false);
+            
+            final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
+            builder.setTitle(getString(R.string.menu_item_add_item));
+            builder.setIcon(0);
+
+            mList = (ExpandableListView)
+                    View.inflate(Launcher.this, R.layout.create_shortcut_list, null);
+            mList.setAdapter(mAdapter);
+            mList.setOnChildClickListener(this);
+            mList.setOnGroupExpandListener(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 boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
+                int childPosition, long id) {
+            mAdapter.performAction(groupPosition, childPosition);
+            cleanup();
+            return true;
+        }
+
+        public void onCancel(DialogInterface dialog) {
+            mWaitingForResult = false;
+            cleanup();
+        }
+
+        private void cleanup() {
+            mWorkspace.unlock();
+            dismissDialog(DIALOG_CREATE_SHORTCUT);
+        }
+
+        public void onGroupExpand(int groupPosition) {
+            long packged = ExpandableListView.getPackedPositionForGroup(groupPosition);
+            int position = mList.getFlatListPosition(packged);
+            mList.setSelectionFromTop(position, 0);
+        }
+    }
+
+    /**
+     * Receives notifications when applications are added/removed.
+     */
+    private class ApplicationsIntentReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            //noinspection ConstantConditions
+            if (REMOVE_SHORTCUT_ON_PACKAGE_REMOVE &&
+                    Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
+            }
+            removeDialog(DIALOG_CREATE_SHORTCUT);
+            sModel.loadApplications(false, Launcher.this);
+        }
+    }
+
+    /**
+     * Receives notifications whenever the user favorites have changed.
+     */
+    private class FavoritesChangeObserver extends ContentObserver {
+        public FavoritesChangeObserver() {
+            super(mHandler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onFavoritesChanged();
+        }
+    }
+
+    private class SensorHandler implements SensorListener {
+        private long mLastNegativeShake;
+        private long mLastPositiveShake;
+
+        public void onSensorChanged(int sensor, float[] values) {
+            if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
+                float shake = values[0];
+                if (shake <= -SensorManager.STANDARD_GRAVITY) {
+                    mLastNegativeShake = SystemClock.uptimeMillis();
+                } else if (shake >= SensorManager.STANDARD_GRAVITY) {
+                    mLastPositiveShake = SystemClock.uptimeMillis();
+                }
+
+                final long difference = mLastPositiveShake - mLastNegativeShake;
+                if (difference <= -80 && difference >= -180) {
+                    mWorkspace.scrollLeft();
+                    mLastNegativeShake = mLastPositiveShake = 0;
+                } else if (difference >= 80 && difference <= 180) {
+                    mWorkspace.scrollRight();
+                    mLastNegativeShake = mLastPositiveShake = 0;
+                }
+            }
+        }
+
+        public void onAccuracyChanged(int sensor, int accuracy) {
+        }
+    }
+
+    /**
+     * 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);
+                mOpen = true;
+            }
+        }
+
+        public void onDrawerClosed() {
+            if (mOpen) {
+                mHandleIcon.reverseTransition(150);
+                mOpen = false;
+            }
+            mAllAppsGrid.setSelection(0);
+            mAllAppsGrid.clearTextFilter();
+            mWorkspace.clearChildrenCache();
+        }
+
+        public void onScrollStarted() {
+            mWorkspace.enableChildrenCache();
+        }
+
+        public void onScrollEnded() {
+        }
+    }
+}
diff --git a/src/com/android/launcher/LauncherModel.java b/src/com/android/launcher/LauncherModel.java
new file mode 100644
index 0000000..8375bbe
--- /dev/null
+++ b/src/com/android/launcher/LauncherModel.java
@@ -0,0 +1,802 @@
+/*
+ * 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.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import com.android.internal.provider.Settings;
+import android.util.Log;
+
+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;
+
+/**
+ * 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 HashMap<Long, UserFolderInfo> mUserFolders;
+
+    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) {
+        if (isLaunching && mApplicationsLoaded) {
+            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
+            return;
+        }
+
+        if (mApplicationsAdapter == null || isLaunching) {
+            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;
+        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;
+
+            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, b.title);
+                    }
+                });
+
+                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.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 && 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) {
+        if (isLaunching && mDesktopItems != null && mDesktopItemsLoaded) {
+            // 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);
+        mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
+        mDesktopLoader.start();
+    }
+
+    private class DesktopItemsLoader implements Runnable {
+        private volatile boolean mStopped;
+        private volatile boolean mRunning;
+
+        private final WeakReference<Launcher> mLauncher;
+
+        DesktopItemsLoader(Launcher launcher) {
+            mLauncher = new WeakReference<Launcher>(launcher);
+        }
+
+        void stop() {
+            mStopped = true;
+        }
+
+        boolean isRunning() {
+            return mRunning;
+        }
+
+        public void run() {
+            mRunning = true;
+
+            final Launcher launcher = mLauncher.get();
+
+            mDesktopItems = new ArrayList<ItemInfo>();
+            mUserFolders = new HashMap<Long, UserFolderInfo>();
+
+            final ArrayList<ItemInfo> desktopItems = mDesktopItems;
+
+            final Cursor c = launcher.getContentResolver().query(Settings.Favorites.CONTENT_URI,
+                    null, null, null, null);
+
+            try {
+                final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID);
+                final int intentIndex = c.getColumnIndexOrThrow(Settings.Favorites.INTENT);
+                final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE);
+                final int iconTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_TYPE);
+                final int iconIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON);
+                final int iconPackageIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_PACKAGE);
+                final int iconResourceIndex = c.getColumnIndexOrThrow(Settings.Favorites.ICON_RESOURCE);
+                final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
+                final int itemTypeIndex = c.getColumnIndexOrThrow(Settings.Favorites.ITEM_TYPE);
+                final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
+                final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
+                final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
+
+                final PackageManager manager = launcher.getPackageManager();
+
+                ApplicationInfo info;
+                String intentDescription;
+                Widget widgetInfo = null;
+                int container;
+
+                final HashMap<Long, UserFolderInfo> userFolders = mUserFolders;
+
+                while (!mStopped && c.moveToNext()) {
+                    try {
+                        int itemType = c.getInt(itemTypeIndex);
+
+                        switch (itemType) {
+                        case Settings.Favorites.ITEM_TYPE_APPLICATION:
+                        case Settings.Favorites.ITEM_TYPE_SHORTCUT:
+                            intentDescription = c.getString(intentIndex);
+                            Intent intent;
+                            try {
+                                intent = Intent.getIntent(intentDescription);
+                            } catch (java.net.URISyntaxException e) {
+                                continue;
+                            }
+
+                            if (itemType == Settings.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 Settings.Favorites.CONTAINER_DESKTOP:
+                                    desktopItems.add(info);
+                                    break;
+                                default:
+                                    // Item is in a user folder
+                                    UserFolderInfo folderInfo =
+                                            findOrMakeFolder(userFolders, container);
+                                    folderInfo.add(info);
+                                    break;
+                                }
+                            }
+                            break;
+                        case Settings.Favorites.ITEM_TYPE_USER_FOLDER:
+
+                            long id = c.getLong(idIndex);
+                            UserFolderInfo folderInfo = findOrMakeFolder(userFolders, 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 Settings.Favorites.CONTAINER_DESKTOP:
+                                desktopItems.add(folderInfo);
+                                break;
+                            default:
+
+                            }
+                            break;
+                        case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
+                        case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
+                        case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
+                            switch (itemType) {
+                            case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
+                                widgetInfo = Widget.makeClock();
+                                break;
+                            case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
+                                widgetInfo = Widget.makeSearch();
+                                break;
+                            case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
+                                widgetInfo = Widget.makePhotoFrame();
+                                byte[] data = c.getBlob(iconIndex);
+                                if (data != null) {
+                                    widgetInfo.photo =
+                                            BitmapFactory.decodeByteArray(data, 0, data.length);
+                                }
+                                break;
+                            }
+
+                            if (widgetInfo != null) {
+                                container = c.getInt(containerIndex);
+                                if (container != Settings.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;
+                        }
+                    } 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 (!mStopped) {
+                mDesktopItemsLoaded = true;
+            }
+            mRunning = false;
+        }
+    }
+
+    /**
+     * 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.
+     */
+    UserFolderInfo findFolderById(long id) {
+        return mUserFolders.get(id);
+    }
+
+    void addUserFolder(UserFolderInfo info) {
+        mUserFolders.put(info.id, info);
+    }
+
+    /**
+     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
+     * new one.
+     */
+    private UserFolderInfo findOrMakeFolder(HashMap<Long, UserFolderInfo> userFolders, long id) {
+        UserFolderInfo folderInfo;
+        // See if a placeholder was created for us already
+        folderInfo = userFolders.get(id);
+        if (folderInfo == null) {
+            // No placeholder -- create a new instance
+            folderInfo = new UserFolderInfo();
+            userFolders.put(id, folderInfo);
+        }
+        return 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);
+    }
+    
+    /**
+     * 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 Settings.Favorites.ITEM_TYPE_APPLICATION:
+                case Settings.Favorites.ITEM_TYPE_SHORTCUT:
+                    ((ApplicationInfo)item).icon.setCallback(null);
+                }
+            }
+        }
+    }
+    
+    /**
+     * 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);
+            }
+        }
+    }
+
+    /**
+     * @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;
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 = Settings.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 = Settings.Favorites.ITEM_TYPE_SHORTCUT;
+
+        int iconType = c.getInt(iconTypeIndex);
+        switch (iconType) {
+            case Settings.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 Settings.Favorites.ICON_TYPE_BITMAP:
+                byte[] data = c.getBlob(iconIndex);
+                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                info.icon = new BitmapDrawable(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) {
+        mUserFolders.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(Settings.Favorites.CONTAINER, item.container);
+        values.put(Settings.Favorites.CELLX, item.cellX);
+        values.put(Settings.Favorites.CELLY, item.cellY);
+        values.put(Settings.Favorites.SCREEN, item.screen);
+
+        cr.update(Settings.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(Settings.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;
+    }
+
+    UserFolderInfo getFolderById(Context context, long id) {
+        final ContentResolver cr = context.getContentResolver();
+        Cursor c = cr.query(Settings.Favorites.CONTENT_URI, null, "_id=? and itemType=?",
+            new String[] { String.valueOf(id),
+                    String.valueOf(Settings.Favorites.ITEM_TYPE_USER_FOLDER) }, null);
+
+        try {
+            if (c.moveToFirst()) {
+                final int titleIndex = c.getColumnIndexOrThrow(Settings.Favorites.TITLE);
+                final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
+                final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
+                final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
+                final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
+
+                UserFolderInfo folderInfo = findOrMakeFolder(mUserFolders, id);
+
+                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;
+    }
+
+    static Widget getPhotoFrameInfo(Context context, int screen, int cellX, int cellY) {
+        final ContentResolver cr = context.getContentResolver();
+        Cursor c = cr.query(Settings.Favorites.CONTENT_URI,
+            null, "screen=? and cellX=? and cellY=? and itemType=?",
+            new String[] { String.valueOf(screen), String.valueOf(cellX), String.valueOf(cellY),
+                String.valueOf(Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) }, null);
+
+        try {
+            if (c.moveToFirst()) {
+                final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites.ID);
+                final int containerIndex = c.getColumnIndexOrThrow(Settings.Favorites.CONTAINER);
+                final int screenIndex = c.getColumnIndexOrThrow(Settings.Favorites.SCREEN);
+                final int cellXIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLX);
+                final int cellYIndex = c.getColumnIndexOrThrow(Settings.Favorites.CELLY);
+
+                Widget widgetInfo = Widget.makePhotoFrame();
+                widgetInfo.id = c.getLong(idIndex);
+                widgetInfo.screen = c.getInt(screenIndex);
+                widgetInfo.container = c.getInt(containerIndex);
+                widgetInfo.cellX = c.getInt(cellXIndex);
+                widgetInfo.cellY = c.getInt(cellYIndex);
+
+                return widgetInfo;
+            }
+        } 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 ? Settings.Favorites.CONTENT_URI :
+                Settings.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(Settings.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(Settings.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(Settings.Favorites.getContentUri(info.id, false), null, null);
+        cr.delete(Settings.Favorites.CONTENT_URI, Settings.Favorites.CONTAINER + "=" + info.id, 
+                null);
+    }
+}
diff --git a/src/com/android/launcher/PhotoFrame.java b/src/com/android/launcher/PhotoFrame.java
new file mode 100644
index 0000000..1151322
--- /dev/null
+++ b/src/com/android/launcher/PhotoFrame.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ImageView;
+
+
+/**
+ * Desktop widget that holds a user folder
+ *
+ */
+public class PhotoFrame extends ImageView implements OnClickListener {
+    
+    public PhotoFrame(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setClickable(true);
+        setOnClickListener(this);
+        setWillNotCacheDrawing(true);
+    }
+    
+    public void onClick(View v) {
+        ((Launcher) mContext).updatePhotoFrame((Widget) getTag());
+    }
+}
diff --git a/src/com/android/launcher/Search.java b/src/com/android/launcher/Search.java
new file mode 100644
index 0000000..69e26ac
--- /dev/null
+++ b/src/com/android/launcher/Search.java
@@ -0,0 +1,594 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+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.Button;
+import android.widget.CursorAdapter;
+import android.widget.Filter;
+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 Button mGoButton;
+    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;
+
+    /**
+     * 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 Search(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+    
+    /**
+     * Implements OnClickListener (for button)
+     */
+    public void onClick(View v) {
+        query();
+    }
+
+    private void query() {
+        String query = mSearchText.getText().toString();
+        if (TextUtils.getTrimmedLength(mSearchText.getText()) == 0) {
+            return;
+        }
+        sendLaunchIntent(Intent.ACTION_SEARCH, null, query, null, 0, null, mSearchable);
+    }
+    
+    /**
+     * 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);
+    }
+    
+    /**
+     * 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) {
+            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) {
+        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 = (Button) findViewById(R.id.go);
+        mGoButton.setOnClickListener(this);
+        mGoButton.setOnKeyListener(this);
+        
+        mSearchText.setOnLongClickListener(this);
+        mGoButton.setOnLongClickListener(this);
+        
+        // disable the button since we start out w/empty input
+        mGoButton.setEnabled(false);
+        mGoButton.setFocusable(false);
+        
+        configureSuggestions();
+    }
+    
+    /** The rest of the class deals with providing search suggestions */
+    
+    /**
+     * Set up the suggestions provider mechanism
+     */
+    private void configureSuggestions() {
+        // get SearchableInfo
+        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;
+        
+        mSearchText.setOnItemClickListener(this);
+        mSearchText.setOnItemSelectedListener(this);
+        
+        // attach the suggestions adapter
+        mSuggestionsAdapter = new SuggestionsAdapter(mContext, 
+                com.android.internal.R.layout.search_dropdown_item_1line, null,
+                SuggestionsAdapter.ONE_LINE_FROM, SuggestionsAdapter.ONE_LINE_TO, mSearchable);
+        mSearchText.setAdapter(mSuggestionsAdapter);
+    }
+    
+    /**
+     * 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);
+                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());
+        }
+    }
+        
+    /**
+     * This class provides the filtering-based interface to suggestions providers.
+     */
+    private static class SuggestionsAdapter extends SimpleCursorAdapter {
+        public final static String[] ONE_LINE_FROM =   { SearchManager.SUGGEST_COLUMN_TEXT_1 };
+        public final static int[] ONE_LINE_TO =        { com.android.internal.R.id.text1 };
+        
+        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/UninstallShortcutReceiver.java b/src/com/android/launcher/UninstallShortcutReceiver.java
new file mode 100644
index 0000000..2d7909e
--- /dev/null
+++ b/src/com/android/launcher/UninstallShortcutReceiver.java
@@ -0,0 +1,64 @@
+/*
+ * 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 java.net.URISyntaxException;
+
+import com.android.internal.provider.Settings;
+
+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(Settings.Favorites.CONTENT_URI,
+                new String[] { "_id", "intent" }, "title=?", new String[]{ name }, null);
+
+            final int intentIndex = c.getColumnIndexOrThrow(Settings.Favorites.INTENT);
+            final int idIndex = c.getColumnIndexOrThrow(Settings.Favorites._ID);
+
+            try {
+                while (c.moveToNext()) {
+                    try {
+                        if (intent.filterEquals(Intent.getIntent(c.getString(intentIndex)))) {
+                            final long id = c.getLong(idIndex);
+                            cr.delete(Settings.Favorites.getContentUri(id, false), null, null);
+                            if (!duplicate) {
+                                break;
+                            }
+                        }
+                    } catch (URISyntaxException e) {
+                        // Ignore
+                    }
+                }
+            } finally {
+                c.close();
+            }
+
+            cr.notifyChange(Settings.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..dee44baa
--- /dev/null
+++ b/src/com/android/launcher/UserFolder.java
@@ -0,0 +1,84 @@
+package com.android.launcher;
+
+import android.content.Context;
+import com.android.internal.provider.Settings;
+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 == Settings.Favorites.ITEM_TYPE_APPLICATION || 
+                itemType == Settings.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 boolean onLongClick(View v) {
+        mLauncher.closeFolder(this);
+        mLauncher.showRenameDialog((UserFolderInfo) mInfo);
+        return true;
+    }
+
+    @Override
+    public void onDropCompleted(View target, boolean success) {
+        if (success) {
+            //noinspection unchecked
+            ArrayAdapter<ApplicationInfo> adapter =
+                    (ArrayAdapter<ApplicationInfo>) mContent.getAdapter();
+            adapter.remove(mDragItem);
+        }
+    }
+
+    void bind(UserFolderInfo info) {
+        mInfo = info;
+        setContentAdapter(new ApplicationsAdapter(mContext, info.contents));
+        mCloseButton.setText(info.title);
+    }
+
+    // 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..075b89a
--- /dev/null
+++ b/src/com/android/launcher/UserFolderInfo.java
@@ -0,0 +1,65 @@
+/*
+ * 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 com.android.internal.provider.Settings;
+
+import java.util.ArrayList;
+
+/**
+ * Represents a folder containing shortcuts or apps.
+ */
+class UserFolderInfo extends FolderInfo {
+    /**
+     * The application name.
+     */
+    CharSequence title;
+
+    /**
+     * The apps and shortcuts 
+     */
+    ArrayList<ApplicationInfo> contents = new ArrayList<ApplicationInfo>();
+    
+    UserFolderInfo() {
+        itemType = Settings.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(Settings.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..2373897
--- /dev/null
+++ b/src/com/android/launcher/Utilities.java
@@ -0,0 +1,180 @@
+/*
+ * 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.drawable.BitmapDrawable;
+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 && (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());
+            icon.setBounds((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height);
+            icon.draw(canvas);
+            icon.setBounds(sOldBounds);
+            icon = new BitmapDrawable(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..268b571
--- /dev/null
+++ b/src/com/android/launcher/WallpaperChooser.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.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 java.io.IOException;
+import java.io.InputStream;
+
+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_ripples_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,
+            R.drawable.wallpaper_dale_chihuly_small,
+            R.drawable.wallpaper_john_maeda_small,
+            R.drawable.wallpaper_marc_ecko_small,
+    };
+
+    private static final Integer[] IMAGE_IDS = {
+            R.drawable.wallpaper_lake,
+            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_ripples,
+            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,
+            R.drawable.wallpaper_dale_chihuly,
+            R.drawable.wallpaper_john_maeda,
+            R.drawable.wallpaper_marc_ecko,
+    };
+
+    private Gallery mGallery;
+    private ImageView mImageView;
+    private boolean mIsWallpaperSet;
+
+    private BitmapFactory.Options mOptions;
+    private Bitmap mBitmap;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        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);
+        
+        Button b = (Button) findViewById(R.id.set);
+        b.setOnClickListener(this);
+
+        mImageView = (ImageView) findViewById(R.id.wallpaper);
+    }
+
+    @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(), IMAGE_IDS[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(IMAGE_IDS[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 THUMB_IDS.length;
+        }
+
+        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(THUMB_IDS[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..b9d8ae6
--- /dev/null
+++ b/src/com/android/launcher/Widget.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+import com.android.internal.provider.Settings;
+
+/**
+ * Represents one instance of a Launcher widget (clock, search, photo frame).
+ *
+ */
+class Widget extends ItemInfo {
+
+    int layoutResource;
+    Bitmap photo;
+
+    static Widget makeClock() {
+        Widget w = new Widget();
+        w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK;
+        w.spanX = 2;
+        w.spanY = 2;
+        w.layoutResource = R.layout.widget_clock;
+        return w;
+    }
+    
+    static Widget makePhotoFrame() {
+        Widget w = new Widget();
+        w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME;
+        w.spanX = 2;
+        w.spanY = 2;
+        w.layoutResource = R.layout.widget_photo_frame;
+        return w;
+    } 
+    
+    static Widget makeSearch() {
+        Widget w = new Widget();
+        w.itemType = Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH;
+        w.spanX = 4;
+        w.spanY = 1;
+        w.layoutResource = R.layout.widget_search;
+        return w;
+    }
+
+    @Override
+    void onAddToDatabase(ContentValues values) { 
+        super.onAddToDatabase(values);
+        writeBitmap(values, photo);
+    }
+
+}
diff --git a/src/com/android/launcher/Workspace.java b/src/com/android/launcher/Workspace.java
new file mode 100644
index 0000000..73cff02
--- /dev/null
+++ b/src/com/android/launcher/Workspace.java
@@ -0,0 +1,1194 @@
+/*
+ * 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.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 com.android.internal.provider.Settings;
+
+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;
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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()));
+        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 = mNextScreen;
+            Launcher.setScreen(mCurrentScreen);
+            mNextScreen = INVALID_SCREEN;
+            clearChildrenCache();
+        }
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        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 = ViewConfiguration.getTouchSlop();
+                
+                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;
+                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();
+
+        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) {
+        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);
+    }
+
+    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,
+                        Settings.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) {
+        // Drag from somewhere else
+        ItemInfo info = (ItemInfo) dragInfo;
+
+        View view;
+
+        switch (info.itemType) {
+        case Settings.Favorites.ITEM_TYPE_APPLICATION:
+        case Settings.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 Settings.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);
+        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,
+                Settings.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 View 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 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);
+        Search searchWidget = (Search)findSearchWidget(currentScreen);
+        if (searchWidget != null) {
+            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;
+                    if (packageName.equals(info.intent.getComponent().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();
+            }
+        }
+    }
+
+    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];
+            }
+        };
+    }
+}
