Merge commit 'korg/cupcake'
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 272f7c1..4b11343 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -71,6 +71,7 @@
             android:clearTaskOnLaunch="true"
             android:stateNotNeeded="true"
             android:theme="@style/Theme"
+            android:screenOrientation="nosensor"
             android:windowSoftInputMode="stateUnspecified|adjustPan">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/res/drawable-land/delete_handle.png b/res/drawable-land/delete_handle.png
index 5784c26..43a9081 100644
--- a/res/drawable-land/delete_handle.png
+++ b/res/drawable-land/delete_handle.png
Binary files differ
diff --git a/res/drawable-land/delete_handle_normal.png b/res/drawable-land/delete_handle_normal.png
index d3a8dba..bc11ff8 100644
--- a/res/drawable-land/delete_handle_normal.png
+++ b/res/drawable-land/delete_handle_normal.png
Binary files differ
diff --git a/res/drawable-land/ic_delete.png b/res/drawable-land/ic_delete.png
index 58871fd..7b0f768 100644
--- a/res/drawable-land/ic_delete.png
+++ b/res/drawable-land/ic_delete.png
Binary files differ
diff --git a/res/drawable-land/ic_tray_collapse.png b/res/drawable-land/ic_tray_collapse.png
index 15c6257..c11f8b3 100644
--- a/res/drawable-land/ic_tray_collapse.png
+++ b/res/drawable-land/ic_tray_collapse.png
Binary files differ
diff --git a/res/drawable-land/ic_tray_expand.png b/res/drawable-land/ic_tray_expand.png
index 38836af..cd3e5a4 100644
--- a/res/drawable-land/ic_tray_expand.png
+++ b/res/drawable-land/ic_tray_expand.png
Binary files differ
diff --git a/res/drawable-land/search_bg.9.png b/res/drawable-land/search_bg.9.png
index 9b11d42..7f105bd 100644
--- a/res/drawable-land/search_bg.9.png
+++ b/res/drawable-land/search_bg.9.png
Binary files differ
diff --git a/res/drawable-land/tray_handle_normal.png b/res/drawable-land/tray_handle_normal.png
index 93b8597..0cd2146 100644
--- a/res/drawable-land/tray_handle_normal.png
+++ b/res/drawable-land/tray_handle_normal.png
Binary files differ
diff --git a/res/drawable-land/tray_handle_pressed.png b/res/drawable-land/tray_handle_pressed.png
index e2cae0e..c875617 100644
--- a/res/drawable-land/tray_handle_pressed.png
+++ b/res/drawable-land/tray_handle_pressed.png
Binary files differ
diff --git a/res/drawable-land/tray_handle_selected.png b/res/drawable-land/tray_handle_selected.png
index 106c8f4..1dfdf1e 100644
--- a/res/drawable-land/tray_handle_selected.png
+++ b/res/drawable-land/tray_handle_selected.png
Binary files differ
diff --git a/res/drawable-port/delete_handle.png b/res/drawable-port/delete_handle.png
index 9ce0924..94a5cd0 100644
--- a/res/drawable-port/delete_handle.png
+++ b/res/drawable-port/delete_handle.png
Binary files differ
diff --git a/res/drawable-port/delete_handle_normal.png b/res/drawable-port/delete_handle_normal.png
index 1f0a7ac..95b3da7 100644
--- a/res/drawable-port/delete_handle_normal.png
+++ b/res/drawable-port/delete_handle_normal.png
Binary files differ
diff --git a/res/drawable-port/ic_delete.png b/res/drawable-port/ic_delete.png
index 88330e7..382cba9 100644
--- a/res/drawable-port/ic_delete.png
+++ b/res/drawable-port/ic_delete.png
Binary files differ
diff --git a/res/drawable-port/ic_tray_collapse.png b/res/drawable-port/ic_tray_collapse.png
index b6b8a77..712d189 100644
--- a/res/drawable-port/ic_tray_collapse.png
+++ b/res/drawable-port/ic_tray_collapse.png
Binary files differ
diff --git a/res/drawable-port/ic_tray_expand.png b/res/drawable-port/ic_tray_expand.png
index d2bbbd0..753a4c9 100644
--- a/res/drawable-port/ic_tray_expand.png
+++ b/res/drawable-port/ic_tray_expand.png
Binary files differ
diff --git a/res/drawable-port/search_bg.9.png b/res/drawable-port/search_bg.9.png
index 4293159..b55b545 100644
--- a/res/drawable-port/search_bg.9.png
+++ b/res/drawable-port/search_bg.9.png
Binary files differ
diff --git a/res/drawable-port/tray_handle_normal.png b/res/drawable-port/tray_handle_normal.png
index bf82049..e989645 100644
--- a/res/drawable-port/tray_handle_normal.png
+++ b/res/drawable-port/tray_handle_normal.png
Binary files differ
diff --git a/res/drawable-port/tray_handle_pressed.png b/res/drawable-port/tray_handle_pressed.png
index b9d8e02..bc6e03f 100644
--- a/res/drawable-port/tray_handle_pressed.png
+++ b/res/drawable-port/tray_handle_pressed.png
Binary files differ
diff --git a/res/drawable-port/tray_handle_selected.png b/res/drawable-port/tray_handle_selected.png
index 01c2522..b319c8d 100644
--- a/res/drawable-port/tray_handle_selected.png
+++ b/res/drawable-port/tray_handle_selected.png
Binary files differ
diff --git a/res/drawable/box_launcher_bottom.9.png b/res/drawable/box_launcher_bottom.9.png
index f4cc1fa..1c99c50 100755
--- a/res/drawable/box_launcher_bottom.9.png
+++ b/res/drawable/box_launcher_bottom.9.png
Binary files differ
diff --git a/res/drawable/box_launcher_top_normal.9.png b/res/drawable/box_launcher_top_normal.9.png
index abaff95..30b17b2 100644
--- a/res/drawable/box_launcher_top_normal.9.png
+++ b/res/drawable/box_launcher_top_normal.9.png
Binary files differ
diff --git a/res/drawable/box_launcher_top_pressed.9.png b/res/drawable/box_launcher_top_pressed.9.png
index 4e163d4..033cd48 100644
--- a/res/drawable/box_launcher_top_pressed.9.png
+++ b/res/drawable/box_launcher_top_pressed.9.png
Binary files differ
diff --git a/res/drawable/box_launcher_top_selected.9.png b/res/drawable/box_launcher_top_selected.9.png
index 01b1c4e..3ef394c 100644
--- a/res/drawable/box_launcher_top_selected.9.png
+++ b/res/drawable/box_launcher_top_selected.9.png
Binary files differ
diff --git a/res/drawable/ic_launcher_application.png b/res/drawable/ic_launcher_application.png
index 7502484..3b28cc6 100644
--- a/res/drawable/ic_launcher_application.png
+++ b/res/drawable/ic_launcher_application.png
Binary files differ
diff --git a/res/drawable/ic_launcher_empty.png b/res/drawable/ic_launcher_empty.png
deleted file mode 100644
index 59bb6c5..0000000
--- a/res/drawable/ic_launcher_empty.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_launcher_folder_live.png b/res/drawable/ic_launcher_folder_live.png
new file mode 100644
index 0000000..2145747
--- /dev/null
+++ b/res/drawable/ic_launcher_folder_live.png
Binary files differ
diff --git a/res/drawable/ic_launcher_shortcut.png b/res/drawable/ic_launcher_shortcut.png
new file mode 100644
index 0000000..d6c0ef4
--- /dev/null
+++ b/res/drawable/ic_launcher_shortcut.png
Binary files differ
diff --git a/res/drawable/ic_search_widget.png b/res/drawable/ic_search_widget.png
index 0a4d8f4..37bf77e 100644
--- a/res/drawable/ic_search_widget.png
+++ b/res/drawable/ic_search_widget.png
Binary files differ
diff --git a/res/drawable/pattern_carbon_fiber_dark.png b/res/drawable/pattern_carbon_fiber_dark.png
new file mode 100644
index 0000000..44e050f
--- /dev/null
+++ b/res/drawable/pattern_carbon_fiber_dark.png
Binary files differ
diff --git a/res/drawable/texture_brushed_steel.png b/res/drawable/texture_brushed_steel.png
deleted file mode 100644
index 73b3dfe..0000000
--- a/res/drawable/texture_brushed_steel.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/wallpaper_dale_chihuly.jpg b/res/drawable/wallpaper_dale_chihuly.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_dale_chihuly.jpg
+++ /dev/null
diff --git a/res/drawable/wallpaper_dale_chihuly_small.jpg b/res/drawable/wallpaper_dale_chihuly_small.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_dale_chihuly_small.jpg
+++ /dev/null
diff --git a/res/drawable/wallpaper_john_maeda.jpg b/res/drawable/wallpaper_john_maeda.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_john_maeda.jpg
+++ /dev/null
diff --git a/res/drawable/wallpaper_john_maeda_small.jpg b/res/drawable/wallpaper_john_maeda_small.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_john_maeda_small.jpg
+++ /dev/null
diff --git a/res/drawable/wallpaper_marc_ecko.jpg b/res/drawable/wallpaper_marc_ecko.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_marc_ecko.jpg
+++ /dev/null
diff --git a/res/drawable/wallpaper_marc_ecko_small.jpg b/res/drawable/wallpaper_marc_ecko_small.jpg
deleted file mode 100644
index e69de29..0000000
--- a/res/drawable/wallpaper_marc_ecko_small.jpg
+++ /dev/null
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 2b262c3..8214863 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -66,7 +66,7 @@
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
 
-            launcher:texture="@drawable/texture_brushed_steel"
+            launcher:texture="@drawable/pattern_carbon_fiber_dark"
 
             android:scrollbarStyle="outsideInset"
             android:drawSelectorOnTop="false"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 0c249a3..7dcacd6 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -66,7 +66,7 @@
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
 
-            launcher:texture="@drawable/texture_brushed_steel"
+            launcher:texture="@drawable/pattern_carbon_fiber_dark"
 
             android:scrollbarStyle="outsideInset"
             android:drawSelectorOnTop="false"
diff --git a/res/layout/create_shortcut_group_item.xml b/res/layout/create_shortcut_group_item.xml
deleted file mode 100644
index 8004633..0000000
--- a/res/layout/create_shortcut_group_item.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/title"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:textAppearance="?android:attr/textAppearanceLargeInverse"
-    android:gravity="center_vertical"
-    android:paddingRight="15dip"
-    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" />
-
diff --git a/res/layout/create_shortcut_list.xml b/res/layout/create_shortcut_list.xml
deleted file mode 100644
index aa16733..0000000
--- a/res/layout/create_shortcut_list.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:layout_marginTop="5dip"
-    android:cacheColorHint="@null"
-    android:divider="@android:drawable/divider_horizontal_bright"
-    android:scrollbars="vertical" />
diff --git a/res/layout/create_shortcut_list_item.xml b/res/layout/create_shortcut_list_item.xml
deleted file mode 100644
index a6975f8..0000000
--- a/res/layout/create_shortcut_list_item.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/title"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:textAppearance="?android:attr/textAppearanceLargeInverse"
-    android:gravity="center_vertical"
-    android:drawablePadding="14dip"
-    android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
-    android:paddingRight="15dip" />
-
-
diff --git a/res/layout/widget_search.xml b/res/layout/widget_search.xml
index 209716d..b4c455c 100644
--- a/res/layout/widget_search.xml
+++ b/res/layout/widget_search.xml
@@ -19,11 +19,13 @@
     android:layout_height="fill_parent"
     android:orientation="horizontal"
     android:background="@drawable/search_bg"
-    android:gravity="center_vertical">
+    android:gravity="center_vertical"
+    >
 
     <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:paddingRight="3dip"
         android:src="@drawable/google_logo" />
         
     <com.android.launcher.SearchAutoCompleteTextView
@@ -31,6 +33,7 @@
         android:layout_width="0dip"
         android:layout_weight="1"
         android:layout_height="wrap_content"
+        android:layout_marginTop="1dip"
         android:hint="@string/search_hint"
         android:focusableInTouchMode="false"
         android:singleLine="true"
@@ -38,16 +41,18 @@
         android:completionThreshold="1"
         android:inputType="textAutoComplete"
         android:imeOptions="actionSearch"
+        android:lines="1"
         />
         
      <ImageButton android:id="@+id/search_go_btn"
-         android:layout_marginLeft="1dip"
+         android:layout_marginLeft="4dip"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:src="@*android:drawable/ic_btn_search"
          />
     
      <ImageButton android:id="@+id/search_voice_btn"
+         android:layout_marginLeft="2dip"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:src="@android:drawable/ic_btn_speak_now"
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index dea039f..ecf6792 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"zápis nastavení a odkazů plochy"</string>
     <string name="permdesc_write_settings">"Povoluje aplikaci změnit nastavení a odkazy plochy."</string>
     <string name="search_hint">"Vyhledávání Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problém s načtením widgetu"</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c405852..ca07fc6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"Einstellungen und Shortcuts für Startseite schreiben"</string>
     <string name="permdesc_write_settings">"Ermöglicht einer Anwendung, die Einstellungen und Shortcuts auf der Startseite zu ändern."</string>
     <string name="search_hint">"Google-Suche"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problem beim Laden des Widgets"</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 20d2605..ecfdd98 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"escribir información de accesos directos y de configuración de la página principal"</string>
     <string name="permdesc_write_settings">"Permite que una aplicación modifique la configuración y los accesos directos de la página principal."</string>
     <string name="search_hint">"Búsqueda de Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problema al cargar el widget"</string>
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c01ef47..203c37b 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"Enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
     <string name="permdesc_write_settings">"Permet à une application de modifier les paramètres et les raccourcis de la page d\'accueil."</string>
     <string name="search_hint">"Recherche Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problème lors du chargement du widget"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 47c6f9f..c061ce7 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"creare impostazioni e scorciatoie in Home"</string>
     <string name="permdesc_write_settings">"Consente a un\'applicazione di modificare le impostazioni e le scorciatoie in Home."</string>
     <string name="search_hint">"Ricerca Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Errore durante il caricamento del widget"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index cf71c65..ccde597 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -26,20 +26,27 @@
     <string name="rename_action">"OK"</string>
     <string name="cancel_action">"キャンセル"</string>
     <string name="menu_item_add_item">"ホーム画面に追加"</string>
-    <string name="group_applications">"アプリケーション"</string>
-    <string name="group_shortcuts">"ショートカット"</string>
+    <!-- no translation found for group_applications (4118484163419674240) -->
+    <skip />
+    <!-- no translation found for group_shortcuts (9133529424900391877) -->
+    <skip />
     <string name="group_search">"検索"</string>
-    <string name="group_folder">"フォルダ"</string>
-    <string name="group_live_folders">"ライブフォルダ"</string>
-    <string name="group_widgets">"ウィジェット"</string>
-    <string name="group_wallpapers">"壁紙"</string>
+    <!-- no translation found for group_folder (5143593791798929193) -->
+    <skip />
+    <!-- no translation found for group_live_folders (2664945399140647217) -->
+    <skip />
+    <!-- no translation found for group_widgets (6704978494073105844) -->
+    <skip />
+    <!-- no translation found for group_wallpapers (1568191644272224858) -->
+    <skip />
     <string name="add_folder">"フォルダ"</string>
     <string name="add_clock">"時計"</string>
     <string name="add_photo_frame">"写真フレーム"</string>
     <string name="add_search">"検索"</string>
     <string name="out_of_space">"ホーム画面に空きスペースがありません。"</string>
     <string name="title_select_shortcut">"ショートカットを選択"</string>
-    <string name="title_select_live_folder">"ライブフォルダを選択"</string>
+    <!-- no translation found for title_select_live_folder (3753447798805166749) -->
+    <skip />
     <string name="menu_add">"追加"</string>
     <string name="menu_wallpaper">"壁紙"</string>
     <string name="menu_search">"検索"</string>
@@ -54,6 +61,5 @@
     <string name="permlab_write_settings">"ホームの設定とショートカットの書き込み"</string>
     <string name="permdesc_write_settings">"ホームの設定とショートカットの変更をアプリケーションに許可します。"</string>
     <string name="search_hint">"Google検索"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"ウィジェットを表示できません"</string>
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 75ad6d8..52c7df5 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"홈 설정 및 바로가기 쓰기"</string>
     <string name="permdesc_write_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 변경할 수 있습니다."</string>
     <string name="search_hint">"Google 검색"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"위젯을 로드하는 중 문제가 발생했습니다."</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index b14a5da..8fdb342 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"skrive skrivebordsinnstillinger og -snarveier"</string>
     <string name="permdesc_write_settings">"Lar applikasjonen endre innstillinger og snarveier på skrivebordet."</string>
     <string name="search_hint">"Google-søk"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problem under lasting av gadget"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index e4959c0..1a07fa6 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"instellingen en snelkoppelingen voor de startpagina schrijven"</string>
     <string name="permdesc_write_settings">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
     <string name="search_hint">"Google Zoeken"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Probleem bij het laden van widget"</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 99718cb..e26d723 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"zapisywanie ustawień i skrótów strony głównej"</string>
     <string name="permdesc_write_settings">"Umożliwia aplikacji zmianę ustawień i skrótów strony głównej."</string>
     <string name="search_hint">"Szukaj w Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Problem podczas ładowania widżetu"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index ab6120e..2546503 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"записывать ярлыки и настройки главного экрана"</string>
     <string name="permdesc_write_settings">"Позволяет приложению изменять настройки и ярлыки на главном экране."</string>
     <string name="search_hint">"Поиск Google"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"Не удалось загрузить виджет"</string>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index f5d929d..a71bb3a 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"写入“主页”设置和快捷键"</string>
     <string name="permdesc_write_settings">"允许应用程序更改“主页”中的设置和快捷键。"</string>
     <string name="search_hint">"Google 搜索"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"载入窗口小部件时出现问题"</string>
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 326f2a2..217444e 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -54,6 +54,5 @@
     <string name="permlab_write_settings">"寫入首頁設定和捷徑"</string>
     <string name="permdesc_write_settings">"允許應用程式變更首頁中的設定和捷徑。"</string>
     <string name="search_hint">"Google 搜尋"</string>
-    <!-- no translation found for gadget_error_text (8359351016167075858) -->
-    <skip />
+    <string name="gadget_error_text">"載入小工具時發生問題"</string>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index ab545aa..1fcad81 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -76,4 +76,12 @@
         <attr name="texture" format="reference"  />
     </declare-styleable>
 
+    <!-- XML attributes used by default_workspace.xml -->
+    <declare-styleable name="Favorite">
+        <attr name="className" format="string" />
+        <attr name="packageName" format="string" />
+        <attr name="screen" format="string" />
+        <attr name="x" format="string" />
+        <attr name="y" format="string" />
+    </declare-styleable>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a7945cb..b0421b2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -49,19 +49,19 @@
     <!-- Title of dialog box -->
     <string name="menu_item_add_item">Add to Home screen</string>
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all apps -->
-    <string name="group_applications">Application</string>
+    <string name="group_applications">Applications</string>
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all shortcuts -->
-    <string name="group_shortcuts">Shortcut</string>
+    <string name="group_shortcuts">Shortcuts</string>
     <!-- Options in "Add to Home" dialog box; Title of the search gadget -->
     <string name="group_search">Search</string>
     <!-- Options in "Add to Home" dialog box; Title of the folder gadget -->
-    <string name="group_folder">Folder</string>
+    <string name="group_folder">New folder</string>
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all live folders -->
-    <string name="group_live_folders">Live folder</string>
+    <string name="group_live_folders">Folders</string>
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all widgets/gadgets -->
-    <string name="group_widgets">Widget</string>
+    <string name="group_widgets">Widgets</string>
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
-    <string name="group_wallpapers">Wallpaper</string>
+    <string name="group_wallpapers">Wallpapers</string>
     <!-- Options in "Add to Home" dialog box; Name of the Folder widget-->
     <string name="add_folder">Folder</string>
     <!-- Options in "Add to Home" dialog box; Name of the Clock widget-->
@@ -76,7 +76,7 @@
     <!-- Title of dialog when user is selecting shortcut to add to homescreen -->
     <string name="title_select_shortcut">Select shortcut</string>
     <!-- Title of dialog when user is selecting live folder to add to homescreen -->
-    <string name="title_select_live_folder">Select live folder</string>
+    <string name="title_select_live_folder">Select folder</string>
 
     <!-- Menus items: -->
     <skip />
diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml
new file mode 100644
index 0000000..fd7adf7
--- /dev/null
+++ b/res/xml/default_workspace.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+
+    <clock
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" />
+
+    <search
+        launcher:screen="2"
+        launcher:x="0"
+        launcher:y="0" />
+
+    <favorite
+        launcher:packageName="com.android.contacts"
+        launcher:className="com.android.contacts.DialtactsActivity"
+        launcher:screen="1"
+        launcher:x="0"
+        launcher:y="3" />
+
+    <favorite
+        launcher:packageName="com.android.contacts"
+        launcher:className="com.android.contacts.DialtactsContactsEntryActivity"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="3" />
+
+    <favorite
+        launcher:packageName="com.android.browser"
+        launcher:className="com.android.browser.BrowserActivity"
+        launcher:screen="1"
+        launcher:x="2"
+        launcher:y="3" />
+
+    <favorite
+        launcher:packageName="com.google.android.apps.maps"
+        launcher:className="com.google.android.maps.MapsActivity"
+        launcher:screen="1"
+        launcher:x="3"
+        launcher:y="3" />
+
+    <favorite
+        launcher:packageName="com.android.mms"
+        launcher:className="com.android.mms.ui.ConversationList"
+        launcher:screen="1"
+        launcher:x="0"
+        launcher:y="2" />
+
+    <favorite
+        launcher:packageName="com.android.vending"
+        launcher:className="com.android.vending.AssetBrowserActivity"
+        launcher:screen="1"
+        launcher:x="3"
+        launcher:y="2" />
+
+</favorites>
diff --git a/src/com/android/launcher/AddAdapter.java b/src/com/android/launcher/AddAdapter.java
index cbcb338..a6c889e 100644
--- a/src/com/android/launcher/AddAdapter.java
+++ b/src/com/android/launcher/AddAdapter.java
@@ -31,19 +31,15 @@
  * Adapter showing the types of items that can be added to a {@link Workspace}.
  */
 public class AddAdapter extends BaseAdapter {
-    
-    private final Launcher mLauncher;
+
     private final LayoutInflater mInflater;
     
     private final ArrayList<ListItem> mItems = new ArrayList<ListItem>();
     
-    public static final int ITEM_APPLICATION = 0;
-    public static final int ITEM_SHORTCUT = 1;
-    public static final int ITEM_SEARCH = 2;
-    public static final int ITEM_APPWIDGET = 3;
-    public static final int ITEM_LIVE_FOLDER = 4;
-    public static final int ITEM_FOLDER = 5;
-    public static final int ITEM_WALLPAPER = 6;
+    public static final int ITEM_SHORTCUT = 0;
+    public static final int ITEM_APPWIDGET = 1;
+    public static final int ITEM_LIVE_FOLDER = 2;
+    public static final int ITEM_WALLPAPER = 3;
     
     /**
      * Specific item in our list.
@@ -66,30 +62,20 @@
     
     public AddAdapter(Launcher launcher) {
         super();
-        
-        mLauncher = launcher;
-        mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         
         // Create default actions
         Resources res = launcher.getResources();
         
-        mItems.add(new ListItem(res, R.string.group_applications,
-                R.drawable.ic_launcher_application, ITEM_APPLICATION));
-        
         mItems.add(new ListItem(res, R.string.group_shortcuts,
-                R.drawable.ic_launcher_empty, ITEM_SHORTCUT));
-        
-        mItems.add(new ListItem(res, R.string.group_search,
-                R.drawable.ic_search_widget, ITEM_SEARCH));
-        
+                R.drawable.ic_launcher_shortcut, ITEM_SHORTCUT));
+
         mItems.add(new ListItem(res, R.string.group_widgets,
                 R.drawable.ic_launcher_appwidget, ITEM_APPWIDGET));
         
         mItems.add(new ListItem(res, R.string.group_live_folders,
-                R.drawable.ic_launcher_empty, ITEM_LIVE_FOLDER));
-        
-        mItems.add(new ListItem(res, R.string.group_folder,
-                R.drawable.ic_launcher_folder, ITEM_FOLDER));
+                R.drawable.ic_launcher_folder_live, ITEM_LIVE_FOLDER));
         
         mItems.add(new ListItem(res, R.string.group_wallpapers,
                 R.drawable.ic_launcher_gallery, ITEM_WALLPAPER));
diff --git a/src/com/android/launcher/Launcher.java b/src/com/android/launcher/Launcher.java
index 17f16a7..7b7802e 100644
--- a/src/com/android/launcher/Launcher.java
+++ b/src/com/android/launcher/Launcher.java
@@ -31,6 +31,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.Intent.ShortcutIconResource;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -46,6 +47,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.MessageQueue;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -57,20 +60,17 @@
 import android.text.TextUtils;
 import android.text.method.TextKeyListener;
 import android.util.Log;
+import static android.util.Log.*;
 import android.view.Display;
-import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.WindowManager;
 import android.view.View.OnLongClickListener;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
 import android.widget.EditText;
-import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
 import android.widget.GridView;
@@ -81,6 +81,7 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.LinkedList;
 
 /**
  * Default launcher application.
@@ -91,6 +92,7 @@
 
     private static final boolean PROFILE_STARTUP = false;
     private static final boolean PROFILE_DRAWER = false;
+    private static final boolean PROFILE_ROTATE = false;
     private static final boolean DEBUG_USER_INTERFACE = false;
 
     private static final int WALLPAPER_SCREENS_SPAN = 2;
@@ -112,6 +114,9 @@
 
     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
 
+    static final String EXTRA_CUSTOM_WIDGET = "custom_widget";
+    static final String SEARCH_WIDGET = "search_widget";
+
     static final int SCREEN_COUNT = 3;
     static final int DEFAULT_SCREN = 1;
     static final int NUMBER_CELLS_X = 4;
@@ -197,6 +202,8 @@
 
     private Bundle mSavedInstanceState;
 
+    private DesktopBinder mBinder;
+    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -352,6 +359,19 @@
         super.onPause();
         closeDrawer(false);        
     }
+    
+    @Override
+    public Object onRetainNonConfigurationInstance() {
+        // Flag any binder to stop early before switching
+        if (mBinder != null) {
+            mBinder.mTerminate = true;
+        }
+        
+        if (PROFILE_ROTATE) {
+            android.os.Debug.startMethodTracing("/sdcard/launcher-rotate");
+        }
+        return null;
+    }
 
     private boolean acceptFilter() {
         final InputMethodManager inputManager = (InputMethodManager)
@@ -385,7 +405,8 @@
                     intent.putExtra(Contacts.Intents.UI.FILTER_TEXT_EXTRA_KEY, str);
                 }
 
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
 
                 try {
                     startActivity(intent);
@@ -603,7 +624,7 @@
         Bundle extras = data.getExtras();
         int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
         
-        Log.d(LOG_TAG, "dumping extras content="+extras.toString());
+        d(LOG_TAG, "dumping extras content="+extras.toString());
         
         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
         
@@ -671,7 +692,7 @@
                     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);
+                    w(LOG_TAG, "Could not load shortcut icon: " + extra);
                 }
             }
         }
@@ -794,7 +815,7 @@
         try {
             mAppWidgetHost.stopListening();
         } catch (NullPointerException ex) {
-            Log.w(LOG_TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);
+            w(LOG_TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);
         }
 
         TextKeyListener.getInstance().release();
@@ -903,21 +924,36 @@
         }
     }
     
+    private void updateShortcutsForPackage(String packageName) {
+        if (packageName != null && packageName.length() > 0) {
+            mWorkspace.updateShortcutsForPackage(packageName);
+        }
+    }
+
     void addAppWidget(Intent data) {
         // TODO: catch bad widget exception when sent
         int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-        AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
 
-        if (appWidget.configure != null) {
-            // Launch over to configure widget, if needed
-            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
-            intent.setComponent(appWidget.configure);
-            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-
-            startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
+        String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
+        if (SEARCH_WIDGET.equals(customWidget)) {
+            // We don't need this any more, since this isn't a real app widget.
+            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+            // add the search widget
+            addSearch();
         } else {
-            // Otherwise just add it
-            onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
+            AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
+
+            if (appWidget.configure != null) {
+                // Launch over to configure widget, if needed
+                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
+                intent.setComponent(appWidget.configure);
+                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+
+                startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
+            } else {
+                // Otherwise just add it
+                onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
+            }
         }
     }
     
@@ -942,11 +978,32 @@
     }
 
     void addShortcut(Intent intent) {
-        startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
+        // Handle case where user selected "Applications"
+        String applicationName = getResources().getString(R.string.group_applications);
+        String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+        
+        if (applicationName != null && applicationName.equals(shortcutName)) {
+            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            
+            Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+            pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
+            startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
+        } else {
+            startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
+        }
     }
 
     void addLiveFolder(Intent intent) {
-        startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
+        // Handle case where user selected "Folder"
+        String folderName = getResources().getString(R.string.group_folder);
+        String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+        
+        if (folderName != null && folderName.equals(shortcutName)) {
+            addFolder(!mDesktopLocked);
+        } else {
+            startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
+        }
     }
 
     void addFolder(boolean insertAtFirst) {
@@ -1008,7 +1065,7 @@
                 final int id = resources.getIdentifier(iconResource.resourceName, null, null);
                 icon = resources.getDrawable(id);
             } catch (Exception e) {
-                Log.w(LOG_TAG, "Could not load live folder icon: " + extra);
+                w(LOG_TAG, "Could not load live folder icon: " + extra);
             }
         }
 
@@ -1107,8 +1164,11 @@
             switch (event.getKeyCode()) {
                 case KeyEvent.KEYCODE_BACK:
                     mWorkspace.dispatchKeyEvent(event); 
-                    closeFolder();
-                    closeDrawer();
+                    if (mDrawer.isOpened()) {
+                        closeDrawer();
+                    } else {
+                        closeFolder();                        
+                    }
                     return true;
                 case KeyEvent.KEYCODE_HOME:
                     return true;
@@ -1163,21 +1223,22 @@
 
     void onDesktopItemsLoaded() {
         if (mDestroyed) return;
-android.util.Log.d("Home", "setting grid adapter");
-        mAllAppsGrid.setAdapter(sModel.getApplicationsAdapter());
         bindDesktopItems();
     }
-
+    
     /**
      * Refreshes the shortcuts shown on the workspace.
      */
     private void bindDesktopItems() {
         final ArrayList<ItemInfo> shortcuts = sModel.getDesktopItems();
         final ArrayList<LauncherAppWidgetInfo> appWidgets = sModel.getDesktopAppWidgets();
-        if (shortcuts == null || appWidgets == null) {
+        final ApplicationsAdapter drawerAdapter = sModel.getApplicationsAdapter();
+        if (shortcuts == null || appWidgets == null || drawerAdapter == null) {
             return;
         }
 
+        mAllAppsGrid.setAdapter(drawerAdapter);
+
         final Workspace workspace = mWorkspace;
         int count = workspace.getChildCount();
         for (int i = 0; i < count; i++) {
@@ -1195,9 +1256,14 @@
                 }
             });
         }
-
-        final DesktopBinder binder = new DesktopBinder(this, shortcuts, appWidgets);
-        binder.startBindingItems();
+        
+        // Flag any old binder to terminate early
+        if (mBinder != null) {
+            mBinder.mTerminate = true;
+        }
+        
+        mBinder = new DesktopBinder(this, shortcuts, appWidgets);
+        mBinder.startBindingItems();
     }
 
     private void bindItems(Launcher.DesktopBinder binder,
@@ -1250,7 +1316,7 @@
 
         if (end >= count) {
             finishBindDesktopItems();
-            binder.startBindingAppWidgets();
+            binder.startBindingAppWidgetsWhenIdle();
         } else {
             binder.obtainMessage(DesktopBinder.MESSAGE_BIND_ITEMS, i, count).sendToTarget();
         }
@@ -1296,44 +1362,44 @@
         mDesktopLocked = false;
         mDrawer.unlock();
     }
-
+    
     private void bindAppWidgets(Launcher.DesktopBinder binder,
-            ArrayList<LauncherAppWidgetInfo> appWidgets, int start, int count) {
-
+            LinkedList<LauncherAppWidgetInfo> appWidgets) {
+        
         final Workspace workspace = mWorkspace;
         final boolean desktopLocked = mDesktopLocked;
 
-        final int end = Math.min(start + DesktopBinder.APPWIDGETS_COUNT, count);
-        int i = start;
-
-        for ( ; i < end; i++) {
-            final LauncherAppWidgetInfo item = appWidgets.get(i);
-                    
+        if (!appWidgets.isEmpty()) {
+            final LauncherAppWidgetInfo item = appWidgets.removeFirst();
+            
             final int appWidgetId = item.appWidgetId;
-            final AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
+            final AppWidgetProviderInfo appWidgetInfo =
+                    mAppWidgetManager.getAppWidgetInfo(appWidgetId);
             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
             
-            if (LOGD) Log.d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s", appWidgetId, appWidgetInfo));
+            if (LOGD) {
+                d(LOG_TAG, String.format("about to setAppWidget for id=%d, info=%s",
+                        appWidgetId, appWidgetInfo));
+            }
             
             item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
             item.hostView.setTag(item);
             
             workspace.addInScreen(item.hostView, item.screen, item.cellX,
                     item.cellY, item.spanX, item.spanY, !desktopLocked);
+    
+            workspace.requestLayout();
         }
 
-        workspace.requestLayout();
-
-        if (end >= count) {
-            finishBindDesktopAppWidgets();
+        if (appWidgets.isEmpty()) {
+            if (PROFILE_ROTATE) {
+                android.os.Debug.stopMethodTracing();
+            }
         } else {
-            binder.obtainMessage(DesktopBinder.MESSAGE_BIND_APPWIDGETS, i, count).sendToTarget();
+            binder.obtainMessage(DesktopBinder.MESSAGE_BIND_APPWIDGETS).sendToTarget();
         }
     }
-    
-    private void finishBindDesktopAppWidgets() {
-    }
-    
+
     DragController getDragController() {
         return mDragLayer;
     }
@@ -1623,11 +1689,10 @@
      * Displays the shortcut creation dialog and launches, if necessary, the
      * appropriate activity.
      */
-    private class CreateShortcut implements AdapterView.OnItemClickListener,
+    private class CreateShortcut implements DialogInterface.OnClickListener,
             DialogInterface.OnCancelListener {
         private AddAdapter mAdapter;
-        private ListView mList;
-        
+
         Dialog createDialog() {
             mWaitingForResult = true;
             
@@ -1635,22 +1700,13 @@
             
             final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
             builder.setTitle(getString(R.string.menu_item_add_item));
-            builder.setIcon(0);
-
-            mList = (ListView)
-                    View.inflate(Launcher.this, R.layout.create_shortcut_list, null);
-            mList.setAdapter(mAdapter);
-            mList.setOnItemClickListener(this);
-            builder.setView(mList);
+            builder.setAdapter(mAdapter, this);
+            
             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;
         }
 
@@ -1664,74 +1720,94 @@
             dismissDialog(DIALOG_CREATE_SHORTCUT);
         }
 
-        public void onItemClick(AdapterView parent, View view, int position, long id) {
-            // handle which item was clicked based on position
-            // this will launch off pick intent
+        /**
+         * Handle the action clicked in the "Add to home" dialog.
+         */
+        public void onClick(DialogInterface dialog, int which) {
+            Resources res = getResources();
+            cleanup();
             
-            Object tag = view.getTag();
-            if (tag instanceof AddAdapter.ListItem) {
-                AddAdapter.ListItem item = (AddAdapter.ListItem) tag;
-                cleanup();
-                switch (item.actionTag) {
-                    case AddAdapter.ITEM_APPLICATION: {
-                        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
-                        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-
-                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
-                        pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
-                        startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
-                        break;
-                    }
-
-                    case AddAdapter.ITEM_SHORTCUT: {
-                        Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
-
-                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
-                        pickIntent.putExtra(Intent.EXTRA_INTENT, shortcutIntent);
-                        pickIntent.putExtra(Intent.EXTRA_TITLE,
-                                getText(R.string.title_select_shortcut));
-                        startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
-                        break;
-                    }
+            switch (which) {
+                case AddAdapter.ITEM_SHORTCUT: {
+                    // Insert extra item to handle picking application
+                    Bundle bundle = new Bundle();
                     
-                    case AddAdapter.ITEM_SEARCH: {
-                        addSearch();
-                        break;
-                    }
+                    ArrayList<String> shortcutNames = new ArrayList<String>();
+                    shortcutNames.add(res.getString(R.string.group_applications));
+                    bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
                     
-                    case AddAdapter.ITEM_APPWIDGET: {
-                        int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
-                        
-                        Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
-                        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-                        startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
-                        break;
-                    }
+                    ArrayList<ShortcutIconResource> shortcutIcons =
+                            new ArrayList<ShortcutIconResource>();
+                    shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
+                            R.drawable.ic_launcher_application));
+                    bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
                     
-                    case AddAdapter.ITEM_LIVE_FOLDER: {
-                        Intent liveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
-
-                        Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
-                        pickIntent.putExtra(Intent.EXTRA_INTENT, liveFolderIntent);
-                        pickIntent.putExtra(Intent.EXTRA_TITLE,
-                                getText(R.string.title_select_live_folder));
-                        startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
-                        break;
-                    }
-
-                    case AddAdapter.ITEM_FOLDER: {
-                        addFolder(!mDesktopLocked);
-                        dismissDialog(DIALOG_CREATE_SHORTCUT);
-                        break;
-                    }
-
-                    case AddAdapter.ITEM_WALLPAPER: {
-                        startWallpaper();
-                        break;
-                    }
-
-                }                
+                    Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+                    pickIntent.putExtra(Intent.EXTRA_INTENT,
+                            new Intent(Intent.ACTION_CREATE_SHORTCUT));
+                    pickIntent.putExtra(Intent.EXTRA_TITLE,
+                            getText(R.string.title_select_shortcut));
+                    pickIntent.putExtras(bundle);
+                    
+                    startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
+                    break;
+                }
                 
+                case AddAdapter.ITEM_APPWIDGET: {
+                    int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
+                    
+                    Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
+                    pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+                    // add the search widget
+                    ArrayList<AppWidgetProviderInfo> customInfo =
+                            new ArrayList<AppWidgetProviderInfo>();
+                    AppWidgetProviderInfo info = new AppWidgetProviderInfo();
+                    info.provider = new ComponentName(getPackageName(), "XXX.YYY");
+                    info.label = getString(R.string.group_search);
+                    info.icon = R.drawable.ic_search_widget;
+                    customInfo.add(info);
+                    pickIntent.putParcelableArrayListExtra(
+                            AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
+                    ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
+                    Bundle b = new Bundle();
+                    b.putString(EXTRA_CUSTOM_WIDGET, SEARCH_WIDGET);
+                    customExtras.add(b);
+                    pickIntent.putParcelableArrayListExtra(
+                            AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
+                    // start the pick activity
+                    startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
+                    break;
+                }
+                
+                case AddAdapter.ITEM_LIVE_FOLDER: {
+                    // Insert extra item to handle inserting folder
+                    Bundle bundle = new Bundle();
+                    
+                    ArrayList<String> shortcutNames = new ArrayList<String>();
+                    shortcutNames.add(res.getString(R.string.group_folder));
+                    bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
+                    
+                    ArrayList<ShortcutIconResource> shortcutIcons =
+                            new ArrayList<ShortcutIconResource>();
+                    shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
+                            R.drawable.ic_launcher_folder));
+                    bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
+
+                    Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+                    pickIntent.putExtra(Intent.EXTRA_INTENT,
+                            new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
+                    pickIntent.putExtra(Intent.EXTRA_TITLE,
+                            getText(R.string.title_select_live_folder));
+                    pickIntent.putExtras(bundle);
+                    
+                    startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
+                    break;
+                }
+
+                case AddAdapter.ITEM_WALLPAPER: {
+                    startWallpaper();
+                    break;
+                }
             }
         }
     }
@@ -1742,23 +1818,47 @@
     private class ApplicationsIntentReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            boolean reloadWorkspace = false;
-android.util.Log.d("Home", "application intent received: " + intent.getAction());
-android.util.Log.d("Home", "  --> " + intent.getData());
-            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
-                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                    removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
-                } else {
-                    reloadWorkspace = true;
-                }
+            final String action = intent.getAction();
+            final String packageName = intent.getData().getSchemeSpecificPart();
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+            if (LauncherModel.DEBUG_LOADERS) {
+                d(LauncherModel.LOG_TAG, "application intent received: " + action +
+                        ", replacing=" + replacing);
+                d(LauncherModel.LOG_TAG, "  --> " + intent.getData());
             }
-            removeDialog(DIALOG_CREATE_SHORTCUT);
-            if (!reloadWorkspace) {
-android.util.Log.d("Home", "  --> loading apps");
-                sModel.loadApplications(false, Launcher.this, false);
+
+            if (!Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+                if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+                    if (!replacing) {
+                        removeShortcutsForPackage(packageName);
+                        if (LauncherModel.DEBUG_LOADERS) {
+                            d(LauncherModel.LOG_TAG, "  --> remove package");
+                        }
+                        sModel.removePackage(Launcher.this, packageName);
+                    }
+                    // else, we are replacing the package, so a PACKAGE_ADDED will be sent
+                    // later, we will update the package at this time
+                } else {
+                    if (!replacing) {
+                        if (LauncherModel.DEBUG_LOADERS) {
+                            d(LauncherModel.LOG_TAG, "  --> add package");
+                        }
+                        sModel.addPackage(Launcher.this, packageName);
+                    } else {
+                        if (LauncherModel.DEBUG_LOADERS) {
+                            d(LauncherModel.LOG_TAG, "  --> update package " + packageName);
+                        }
+                        sModel.updatePackage(Launcher.this, packageName);
+                        updateShortcutsForPackage(packageName);
+                    }
+                }
+                removeDialog(DIALOG_CREATE_SHORTCUT);
             } else {
-android.util.Log.d("Home", "  --> loading workspace");
-                sModel.loadUserItems(false, Launcher.this, false, true);
+                if (LauncherModel.DEBUG_LOADERS) {
+                    d(LauncherModel.LOG_TAG, "  --> sync package " + packageName);
+                }
+                sModel.syncPackage(Launcher.this, packageName);
             }
         }
     }
@@ -1865,37 +1965,64 @@
         }
     }
 
-    private static class DesktopBinder extends Handler {
+    private static class DesktopBinder extends Handler implements MessageQueue.IdleHandler {
         static final int MESSAGE_BIND_ITEMS = 0x1;
         static final int MESSAGE_BIND_APPWIDGETS = 0x2;
+        
         // Number of items to bind in every pass
         static final int ITEMS_COUNT = 6;
-        static final int APPWIDGETS_COUNT = 1;
 
         private final ArrayList<ItemInfo> mShortcuts;
-        private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
+        private final LinkedList<LauncherAppWidgetInfo> mAppWidgets;
         private final WeakReference<Launcher> mLauncher;
+        
+        public volatile boolean mTerminate = false;
 
         DesktopBinder(Launcher launcher, ArrayList<ItemInfo> shortcuts,
                 ArrayList<LauncherAppWidgetInfo> appWidgets) {
 
             mLauncher = new WeakReference<Launcher>(launcher);
             mShortcuts = shortcuts;
-            mAppWidgets = appWidgets;
+            
+            // Sort widgets so active workspace is bound first
+            final int currentScreen = launcher.mWorkspace.getCurrentScreen();
+            final int size = appWidgets.size();
+            mAppWidgets = new LinkedList<LauncherAppWidgetInfo>();
+            
+            for (int i = 0; i < size; i++) {
+                LauncherAppWidgetInfo appWidgetInfo = appWidgets.get(i);
+                if (appWidgetInfo.screen == currentScreen) {
+                    mAppWidgets.addFirst(appWidgetInfo);
+                } else {
+                    mAppWidgets.addLast(appWidgetInfo);
+                }
+            }
         }
         
         public void startBindingItems() {
             obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts.size()).sendToTarget();
         }
-
-        public void startBindingAppWidgets() {
-            obtainMessage(MESSAGE_BIND_APPWIDGETS, 0, mAppWidgets.size()).sendToTarget();
+        
+        public void startBindingAppWidgetsWhenIdle() {
+            // Ask for notification when message queue becomes idle
+            final MessageQueue messageQueue = Looper.myQueue();
+            messageQueue.addIdleHandler(this);
         }
         
+        public boolean queueIdle() {
+            // Queue is idle, so start binding items
+            startBindingAppWidgets();
+            return false;
+        }
+
+        public void startBindingAppWidgets() {
+            obtainMessage(MESSAGE_BIND_APPWIDGETS).sendToTarget();
+        }
+
         @Override
         public void handleMessage(Message msg) {
             Launcher launcher = mLauncher.get();
-            if (launcher == null) {
+            if (launcher == null || mTerminate) {
                 return;
             }
             
@@ -1905,7 +2032,7 @@
                     break;
                 }
                 case MESSAGE_BIND_APPWIDGETS: {
-                    launcher.bindAppWidgets(this, mAppWidgets, msg.arg1, msg.arg2);
+                    launcher.bindAppWidgets(this, mAppWidgets);
                     break;
                 }
             }
diff --git a/src/com/android/launcher/LauncherModel.java b/src/com/android/launcher/LauncherModel.java
index 70b4c10..e302081 100644
--- a/src/com/android/launcher/LauncherModel.java
+++ b/src/com/android/launcher/LauncherModel.java
@@ -28,8 +28,9 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.util.Log;
+import static android.util.Log.*;
 import android.os.Process;
 
 import java.util.ArrayList;
@@ -46,13 +47,14 @@
  * for the Launcher.
  */
 public class LauncherModel {
+    static final boolean DEBUG_LOADERS = true;
+    static final String LOG_TAG = "HomeLoaders";
+
     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 static final int INITIAL_ICON_CACHE_CAPACITY = 50;
 
-    private static final boolean DEBUG = false;
-
     private static final Collator sCollator = Collator.getInstance();
 
     private boolean mApplicationsLoaded;
@@ -101,14 +103,16 @@
      */
     synchronized boolean loadApplications(boolean isLaunching, Launcher launcher,
             boolean localeChanged) {
-android.util.Log.d("Home", "load applications");
+
+        if (DEBUG_LOADERS) d(LOG_TAG, "load applications");
+
         if (isLaunching && mApplicationsLoaded && !localeChanged) {
             mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
-android.util.Log.d("Home", "  --> applications loaded, return");
+            if (DEBUG_LOADERS) d(LOG_TAG, "  --> applications loaded, return");
             return false;
         }
 
-        waitForApplicationsLoader();
+        stopAndWaitForApplicationsLoader();
 
         if (localeChanged) {
             dropApplicationCache();
@@ -129,9 +133,9 @@
         return true;
     }
 
-    private synchronized void waitForApplicationsLoader() {
+    private synchronized void stopAndWaitForApplicationsLoader() {
         if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
-            android.util.Log.d("Home", "  --> wait for applications loader");
+            if (DEBUG_LOADERS) d(LOG_TAG, "  --> wait for applications loader");
 
             mApplicationsLoader.stop();
             // Wait for the currently running thread to finish, this can take a little
@@ -145,14 +149,310 @@
     }
 
     private synchronized void startApplicationsLoader(Launcher launcher) {
-android.util.Log.d("Home", "  --> starting applications loader");
-        waitForApplicationsLoader();
+        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting applications loader");
+
+        stopAndWaitForApplicationsLoader();
 
         mApplicationsLoader = new ApplicationsLoader(launcher);
         mApplicationsLoaderThread = new Thread(mApplicationsLoader, "Applications Loader");
         mApplicationsLoaderThread.start();
     }
 
+    synchronized void addPackage(Launcher launcher, String packageName) {
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            startApplicationsLoader(launcher);
+            return;
+        }
+
+        if (packageName != null && packageName.length() > 0) {
+            final PackageManager packageManager = launcher.getPackageManager();
+            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
+
+            if (matches.size() > 0) {
+                final ApplicationsAdapter adapter = mApplicationsAdapter;
+                final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
+
+                for (ResolveInfo info : matches) {
+                    adapter.setNotifyOnChange(false);
+                    adapter.add(makeAndCacheApplicationInfo(packageManager, cache, info));
+                }
+
+                adapter.sort(new ApplicationInfoComparator());
+                adapter.notifyDataSetChanged();
+            }
+        }
+    }
+
+    synchronized void removePackage(Launcher launcher, String packageName) {
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            dropApplicationCache(); // TODO: this could be optimized
+            startApplicationsLoader(launcher);
+            return;
+        }
+
+        if (packageName != null && packageName.length() > 0) {
+            final ApplicationsAdapter adapter = mApplicationsAdapter;
+
+            final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
+            final int count = adapter.getCount();
+
+            for (int i = 0; i < count; i++) {
+                final ApplicationInfo applicationInfo = adapter.getItem(i);
+                final Intent intent = applicationInfo.intent;
+                final ComponentName component = intent.getComponent();
+                if (packageName.equals(component.getPackageName())) {
+                    toRemove.add(applicationInfo);
+                }
+            }
+
+            final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
+            for (ApplicationInfo info : toRemove) {
+                adapter.setNotifyOnChange(false);
+                adapter.remove(info);
+                cache.remove(info.intent.getComponent());
+            }
+
+            if (toRemove.size() > 0) {
+                adapter.sort(new ApplicationInfoComparator());
+                adapter.notifyDataSetChanged();
+            }
+        }
+    }
+
+    synchronized void updatePackage(Launcher launcher, String packageName) {
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            startApplicationsLoader(launcher);
+            return;
+        }
+
+        if (packageName != null && packageName.length() > 0) {
+            final PackageManager packageManager = launcher.getPackageManager();
+            final ApplicationsAdapter adapter = mApplicationsAdapter;
+
+            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
+            final int count = matches.size();
+
+            boolean changed = false;
+
+            for (int i = 0; i < count; i++) {
+                final ResolveInfo info = matches.get(i);
+                final ApplicationInfo applicationInfo = findIntent(adapter,
+                        info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
+                if (applicationInfo != null) {
+                    updateAndCacheApplicationInfo(packageManager, info, applicationInfo);
+                    changed = true;
+                }
+            }
+
+            if (changed) {
+                adapter.sort(new ApplicationInfoComparator());
+                adapter.notifyDataSetChanged();
+            }
+        }
+    }
+
+    private void updateAndCacheApplicationInfo(PackageManager packageManager, ResolveInfo info,
+            ApplicationInfo applicationInfo) {
+
+        updateApplicationInfoTitleAndIcon(packageManager, info, applicationInfo);
+
+        ComponentName componentName = new ComponentName(
+                info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
+        mAppInfoCache.put(componentName, applicationInfo);
+    }
+
+    synchronized void syncPackage(Launcher launcher, String packageName) {
+        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
+            startApplicationsLoader(launcher);
+            return;
+        }
+
+        if (packageName != null && packageName.length() > 0) {
+            final PackageManager packageManager = launcher.getPackageManager();
+            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
+
+            if (matches.size() > 0) {
+                final ApplicationsAdapter adapter = mApplicationsAdapter;
+
+                // Find disabled activities and remove them from the adapter
+                boolean removed = removeDisabledActivities(packageName, matches, adapter);
+                // Find enable activities and add them to the adapter
+                // Also updates existing activities with new labels/icons
+                boolean added = addEnabledAndUpdateActivities(matches, adapter, launcher);
+
+                if (added || removed) {
+                    adapter.sort(new ApplicationInfoComparator());
+                    adapter.notifyDataSetChanged();
+                }
+            }
+        }
+    }
+
+    private static List<ResolveInfo> findActivitiesForPackage(PackageManager packageManager,
+            String packageName) {
+
+        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
+        final List<ResolveInfo> matches = new ArrayList<ResolveInfo>();
+
+        if (apps != null) {
+            // Find all activities that match the packageName
+            int count = apps.size();
+            for (int i = 0; i < count; i++) {
+                final ResolveInfo info = apps.get(i);
+                final ActivityInfo activityInfo = info.activityInfo;
+                if (packageName.equals(activityInfo.packageName)) {
+                    matches.add(info);
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    private boolean addEnabledAndUpdateActivities(List<ResolveInfo> matches,
+            ApplicationsAdapter adapter, Launcher launcher) {
+
+        final List<ApplicationInfo> toAdd = new ArrayList<ApplicationInfo>();
+        final int count = matches.size();
+
+        boolean changed = false;
+
+        for (int i = 0; i < count; i++) {
+            final ResolveInfo info = matches.get(i);
+            final ApplicationInfo applicationInfo = findIntent(adapter,
+                    info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
+            if (applicationInfo == null) {
+                toAdd.add(makeAndCacheApplicationInfo(launcher.getPackageManager(),
+                        mAppInfoCache, info));
+                changed = true;
+            } else {
+                updateAndCacheApplicationInfo(launcher.getPackageManager(), info, applicationInfo);
+                changed = true;
+            }
+        }
+
+        for (ApplicationInfo info : toAdd) {
+            adapter.setNotifyOnChange(false);
+            adapter.add(info);
+        }
+
+        return changed;
+    }
+
+    private boolean removeDisabledActivities(String packageName, List<ResolveInfo> matches,
+            ApplicationsAdapter adapter) {
+
+        final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
+        final int count = adapter.getCount();
+
+        boolean changed = false;
+
+        for (int i = 0; i < count; i++) {
+            final ApplicationInfo applicationInfo = adapter.getItem(i);
+            final Intent intent = applicationInfo.intent;
+            final ComponentName component = intent.getComponent();
+            if (packageName.equals(component.getPackageName())) {
+                if (!findIntent(matches, component)) {
+                    toRemove.add(applicationInfo);
+                    changed = true;
+                }
+            }
+        }
+
+        final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
+        for (ApplicationInfo info : toRemove) {
+            adapter.setNotifyOnChange(false);
+            adapter.remove(info);
+            cache.remove(info.intent.getComponent());
+        }
+
+        return changed;
+    }
+
+    private static ApplicationInfo findIntent(ApplicationsAdapter adapter, String packageName,
+            String name) {
+
+        final int count = adapter.getCount();
+        for (int i = 0; i < count; i++) {
+            final ApplicationInfo applicationInfo = adapter.getItem(i);
+            final Intent intent = applicationInfo.intent;
+            final ComponentName component = intent.getComponent();
+            if (packageName.equals(component.getPackageName()) &&
+                    name.equals(component.getClassName())) {
+                return applicationInfo;
+            }
+        }
+
+        return null;
+    }
+
+    private static boolean findIntent(List<ResolveInfo> apps, ComponentName component) {
+        final String className = component.getClassName();
+        for (ResolveInfo info : apps) {
+            final ActivityInfo activityInfo = info.activityInfo;
+            if (activityInfo.name.equals(className)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    Drawable getApplicationInfoIcon(PackageManager manager, ApplicationInfo info) {
+        final ResolveInfo resolveInfo = manager.resolveActivity(info.intent, 0);
+        if (resolveInfo == null) {
+            return null;
+        }
+
+        ComponentName componentName = new ComponentName(
+                resolveInfo.activityInfo.applicationInfo.packageName,
+                resolveInfo.activityInfo.name);
+        ApplicationInfo application = mAppInfoCache.get(componentName);
+
+        if (application == null) {
+            return resolveInfo.activityInfo.loadIcon(manager);
+        }
+
+        return application.icon;
+    }
+
+    private static ApplicationInfo makeAndCacheApplicationInfo(PackageManager manager,
+            HashMap<ComponentName, ApplicationInfo> appInfoCache, ResolveInfo info) {
+
+        ComponentName componentName = new ComponentName(
+                info.activityInfo.applicationInfo.packageName,
+                info.activityInfo.name);
+        ApplicationInfo application = appInfoCache.get(componentName);
+
+        if (application == null) {
+            application = new ApplicationInfo();
+            application.container = ItemInfo.NO_ID;
+
+            updateApplicationInfoTitleAndIcon(manager, info, application);
+
+            application.setActivity(componentName,
+                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+            appInfoCache.put(componentName, application);
+        }
+
+        return application;
+    }
+
+    private static void updateApplicationInfoTitleAndIcon(PackageManager manager, ResolveInfo info,
+            ApplicationInfo application) {
+
+        application.title = info.loadLabel(manager);
+        if (application.title == null) {
+            application.title = info.activityInfo.name;
+        }
+
+        application.icon = info.activityInfo.loadIcon(manager);
+        application.filtered = false;
+    }
+
     private class ApplicationsLoader implements Runnable {
         private final WeakReference<Launcher> mLauncher;
 
@@ -176,7 +476,7 @@
 
             android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
-            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
             mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
 
             final Launcher launcher = mLauncher.get();
@@ -185,6 +485,8 @@
 
             if (apps != null && !mStopped) {
                 final int count = apps.size();
+                // Can be set to null on the UI thread by the unbind() method
+                // Do not access without checking for null first
                 final ApplicationsAdapter applicationList = mApplicationsAdapter;
 
                 ChangeNotifier action = new ChangeNotifier(applicationList, true);
@@ -192,28 +494,10 @@
 
                 for (int i = 0; i < count && !mStopped; i++) {
                     ResolveInfo info = apps.get(i);
-                    ComponentName componentName = new ComponentName(
-                            info.activityInfo.applicationInfo.packageName,
-                            info.activityInfo.name);
-                    ApplicationInfo application = appInfoCache.get(componentName);
-                    if (application == null) {
-                        application = new ApplicationInfo();
-                        application.title = info.loadLabel(manager);
-                        if (application.title == null) {
-                            application.title = info.activityInfo.name;
-                        }
-                        application.setActivity(componentName,
-                                Intent.FLAG_ACTIVITY_NEW_TASK |
-                                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-                        application.container = ItemInfo.NO_ID;
-                        application.icon = info.activityInfo.loadIcon(manager);
-                        if (DEBUG) {
-                            Log.d(Launcher.LOG_TAG, "Loaded ApplicationInfo for " + componentName);
-                        }
-                        appInfoCache.put(componentName, application);
-                    }
+                    ApplicationInfo application =
+                            makeAndCacheApplicationInfo(manager, appInfoCache, info);
 
-                    if (action.add(application)) {
+                    if (action.add(application) && !mStopped) {
                         launcher.runOnUiThread(action);
                         action = new ChangeNotifier(applicationList, false);
                     }
@@ -229,7 +513,7 @@
         }
     }
 
-    private static class ChangeNotifier implements Runnable, Comparator<ApplicationInfo> {
+    private static class ChangeNotifier implements Runnable {
         private final ApplicationsAdapter mApplicationList;
         private final ArrayList<ApplicationInfo> mBuffer;
 
@@ -243,6 +527,8 @@
 
         public void run() {
             final ApplicationsAdapter applicationList = mApplicationList;
+            // Can be set to null on the UI thread by the unbind() method
+            if (applicationList == null) return;
 
             if (mFirst) {
                 applicationList.setNotifyOnChange(false);
@@ -260,7 +546,7 @@
 
             buffer.clear();
 
-            applicationList.sort(this);
+            applicationList.sort(new ApplicationInfoComparator());
             applicationList.notifyDataSetChanged();
         }
 
@@ -269,7 +555,9 @@
             buffer.add(application);
             return buffer.size() >= UI_NOTIFICATION_RATE;
         }
+    }
 
+    private static class ApplicationInfoComparator implements Comparator<ApplicationInfo> {
         public final int compare(ApplicationInfo a, ApplicationInfo b) {
             return sCollator.compare(a.title.toString(), b.title.toString());
         }
@@ -285,10 +573,10 @@
      */
     void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
             boolean loadApplications) {
-android.util.Log.d("Home", "loading user items");
+        if (DEBUG_LOADERS) d(LOG_TAG, "loading user items");
 
         if (isLaunching && isDesktopLoaded()) {
-android.util.Log.d("Home", "  --> items loaded, return");
+            if (DEBUG_LOADERS) d(LOG_TAG, "  --> items loaded, return");
             if (loadApplications) startApplicationsLoader(launcher);
             // We have already loaded our data from the DB
             launcher.onDesktopItemsLoaded();
@@ -306,7 +594,7 @@
             }
         }
 
-android.util.Log.d("Home", "  --> starting workspace loader");
+        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting workspace loader");
         mDesktopItemsLoaded = false;
         mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
         mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
@@ -563,7 +851,7 @@
 
                             container = c.getInt(containerIndex);
                             if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                                Log.e(Launcher.LOG_TAG, "Widget found where container "
+                                e(Launcher.LOG_TAG, "Widget found where container "
                                         + "!= CONTAINER_DESKTOP  ignoring!");
                                 continue;
                             }
@@ -589,7 +877,7 @@
 
                             container = c.getInt(containerIndex);
                             if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                                Log.e(Launcher.LOG_TAG, "Widget found where container "
+                                e(Launcher.LOG_TAG, "Widget found where container "
                                         + "!= CONTAINER_DESKTOP -- ignoring!");
                                 continue;
                             }
@@ -599,7 +887,7 @@
                             break;
                         }
                     } catch (Exception e) {
-                        Log.w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
+                        w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
                     }
                 }
             } finally {
@@ -699,6 +987,8 @@
      * Home screen on orientation change.
      */
     void unbind() {
+        // Interrupt the applications loader before setting the adapter to null
+        stopAndWaitForApplicationsLoader();
         mApplicationsAdapter = null;
         unbindAppDrawables(mApplications);
         unbindDrawables(mDesktopItems);
diff --git a/src/com/android/launcher/LauncherProvider.java b/src/com/android/launcher/LauncherProvider.java
index 5cd7a0f..e63ef30 100644
--- a/src/com/android/launcher/LauncherProvider.java
+++ b/src/com/android/launcher/LauncherProvider.java
@@ -24,6 +24,8 @@
 import android.content.ComponentName;
 import android.content.ContentUris;
 import android.content.ContentResolver;
+import android.content.res.XmlResourceParser;
+import android.content.res.TypedArray;
 import android.content.pm.PackageManager;
 import android.content.pm.ActivityInfo;
 import android.database.sqlite.SQLiteOpenHelper;
@@ -33,19 +35,17 @@
 import android.database.SQLException;
 import android.util.Log;
 import android.util.Xml;
+import android.util.AttributeSet;
 import android.net.Uri;
 import android.text.TextUtils;
 import android.os.*;
 import android.provider.Settings;
 
-import java.io.FileReader;
-import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParser;
 import com.android.internal.util.XmlUtils;
 import com.android.launcher.LauncherSettings.Favorites;
 
@@ -162,19 +162,10 @@
     }
 
     private static class DatabaseHelper extends SQLiteOpenHelper {
-        /**
-         * Path to file containing default favorite packages, relative to ANDROID_ROOT.
-         */
-        private static final String DEFAULT_FAVORITES_PATH = "etc/favorites.xml";
-
         private static final String TAG_FAVORITES = "favorites";
         private static final String TAG_FAVORITE = "favorite";
-        private static final String TAG_PACKAGE = "package";
-        private static final String TAG_CLASS = "class";
-
-        private static final String ATTRIBUTE_SCREEN = "screen";
-        private static final String ATTRIBUTE_X = "x";
-        private static final String ATTRIBUTE_Y = "y";
+        private static final String TAG_CLOCK = "clock";
+        private static final String TAG_SEARCH = "search";
 
         private final Context mContext;
         private final AppWidgetHost mAppWidgetHost;
@@ -217,7 +208,7 @@
             
             if (!convertDatabase(db)) {
                 // Populate favorites table with initial favorites
-                loadFavorites(db, DEFAULT_FAVORITES_PATH);
+                loadFavorites(db);
             }
         }
 
@@ -445,115 +436,122 @@
          * Loads the default set of favorite packages from an xml file.
          *
          * @param db The database to write the values into
-         * @param subPath The relative path from ANDROID_ROOT to the file to read
          */
-        private int loadFavorites(SQLiteDatabase db, String subPath) {
-            FileReader favReader;
-
-            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
-            final File favFile = new File(Environment.getRootDirectory(), subPath);
-            try {
-                favReader = new FileReader(favFile);
-            } catch (FileNotFoundException e) {
-                Log.e(LOG_TAG, "Couldn't find or open favorites file " + favFile);
-                return 0;
-            }
-
+        private int loadFavorites(SQLiteDatabase db) {
             Intent intent = new Intent(Intent.ACTION_MAIN, null);
             intent.addCategory(Intent.CATEGORY_LAUNCHER);
             ContentValues values = new ContentValues();
 
             PackageManager packageManager = mContext.getPackageManager();
-            ActivityInfo info;
             int i = 0;
             try {
-                XmlPullParser parser = Xml.newPullParser();
-                parser.setInput(favReader);
-
+                XmlResourceParser parser = mContext.getResources().getXml(R.xml.default_workspace);
+                AttributeSet attrs = Xml.asAttributeSet(parser);
                 XmlUtils.beginDocument(parser, TAG_FAVORITES);
 
-                while (true) {
-                    XmlUtils.nextElement(parser);
+                final int depth = parser.getDepth();
 
-                    String name = parser.getName();
-                    if (!TAG_FAVORITE.equals(name)) {
-                        break;
+                int type;
+                while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                        parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+
+                    if (type != XmlPullParser.START_TAG) {
+                        continue;
                     }
 
-                    String pkg = parser.getAttributeValue(null, TAG_PACKAGE);
-                    String cls = parser.getAttributeValue(null, TAG_CLASS);
-                    try {
-                        ComponentName cn = new ComponentName(pkg, cls);
-                        info = packageManager.getActivityInfo(cn, 0);
-                        intent.setComponent(cn);
-                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        values.put(LauncherSettings.Favorites.INTENT, intent.toURI());
-                        values.put(LauncherSettings.Favorites.TITLE,
-                                info.loadLabel(packageManager).toString());
-                        values.put(LauncherSettings.Favorites.CONTAINER,
-                                LauncherSettings.Favorites.CONTAINER_DESKTOP);
-                        values.put(LauncherSettings.Favorites.ITEM_TYPE,
-                                LauncherSettings.Favorites.ITEM_TYPE_APPLICATION);
-                        values.put(LauncherSettings.Favorites.SCREEN,
-                                parser.getAttributeValue(null, ATTRIBUTE_SCREEN));
-                        values.put(LauncherSettings.Favorites.CELLX,
-                                parser.getAttributeValue(null, ATTRIBUTE_X));
-                        values.put(LauncherSettings.Favorites.CELLY,
-                                parser.getAttributeValue(null, ATTRIBUTE_Y));
-                        values.put(LauncherSettings.Favorites.SPANX, 1);
-                        values.put(LauncherSettings.Favorites.SPANY, 1);
-                        db.insert(TABLE_FAVORITES, null, values);
-                        i++;
-                    } catch (PackageManager.NameNotFoundException e) {
-                        Log.w(LOG_TAG, "Unable to add favorite: " + pkg + "/" + cls, e);
+                    boolean added = false;
+                    final String name = parser.getName();
+
+                    TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);
+
+                    values.clear();                    
+                    values.put(LauncherSettings.Favorites.CONTAINER,
+                            LauncherSettings.Favorites.CONTAINER_DESKTOP);
+                    values.put(LauncherSettings.Favorites.SCREEN,
+                            a.getString(R.styleable.Favorite_screen));
+                    values.put(LauncherSettings.Favorites.CELLX,
+                            a.getString(R.styleable.Favorite_x));
+                    values.put(LauncherSettings.Favorites.CELLY,
+                            a.getString(R.styleable.Favorite_y));
+
+                    if (TAG_FAVORITE.equals(name)) {
+                        added = addShortcut(db, values, a, packageManager, intent);
+                    } else if (TAG_SEARCH.equals(name)) {
+                        added = addSearchWidget(db, values);
+                    } else if (TAG_CLOCK.equals(name)) {
+                        added = addClockWidget(db, values);
                     }
+
+                    if (added) i++;
+
+                    a.recycle();
                 }
             } catch (XmlPullParserException e) {
                 Log.w(LOG_TAG, "Got exception parsing favorites.", e);
             } catch (IOException e) {
                 Log.w(LOG_TAG, "Got exception parsing favorites.", e);
             }
-            
+
+            return i;
+        }
+
+        private boolean addShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
+                PackageManager packageManager, Intent intent) {
+
+            ActivityInfo info;
+            String packageName = a.getString(R.styleable.Favorite_packageName);
+            String className = a.getString(R.styleable.Favorite_className);
+            try {
+                ComponentName cn = new ComponentName(packageName, className);
+                info = packageManager.getActivityInfo(cn, 0);
+                intent.setComponent(cn);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                values.put(Favorites.INTENT, intent.toURI());
+                values.put(Favorites.TITLE, info.loadLabel(packageManager).toString());
+                values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
+                values.put(Favorites.SPANX, 1);
+                values.put(Favorites.SPANY, 1);
+                db.insert(TABLE_FAVORITES, null, values);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(LOG_TAG, "Unable to add favorite: " + packageName +
+                        "/" + className, e);
+                return false;
+            }
+            return true;
+        }
+
+        private boolean addSearchWidget(SQLiteDatabase db, ContentValues values) {
             // Add a search box
-            values.clear();
-            values.put(LauncherSettings.Favorites.CONTAINER,
-                    LauncherSettings.Favorites.CONTAINER_DESKTOP);
-            values.put(LauncherSettings.Favorites.ITEM_TYPE,
-                    LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH);
-            values.put(LauncherSettings.Favorites.SCREEN, 2);
-            values.put(LauncherSettings.Favorites.CELLX, 0);
-            values.put(LauncherSettings.Favorites.CELLY, 0);
-            values.put(LauncherSettings.Favorites.SPANX, 4);
-            values.put(LauncherSettings.Favorites.SPANY, 1);
+            values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_WIDGET_SEARCH);
+            values.put(Favorites.SPANX, 4);
+            values.put(Favorites.SPANY, 1);
             db.insert(TABLE_FAVORITES, null, values);
-            
+
+            return true;
+        }
+
+        private boolean addClockWidget(SQLiteDatabase db, ContentValues values) {
             final int[] bindSources = new int[] {
                     Favorites.ITEM_TYPE_WIDGET_CLOCK,
             };
-            
+
             final ArrayList<ComponentName> bindTargets = new ArrayList<ComponentName>();
             bindTargets.add(new ComponentName("com.android.alarmclock",
                     "com.android.alarmclock.AnalogAppWidgetProvider"));
-            
+
             boolean allocatedAppWidgets = false;
-            
+
             // Try binding to an analog clock widget
             try {
                 int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
-                
-                values.clear();
-                values.put(LauncherSettings.Favorites.CONTAINER,
-                        LauncherSettings.Favorites.CONTAINER_DESKTOP);
-                values.put(LauncherSettings.Favorites.ITEM_TYPE,
-                        LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK);
-                values.put(LauncherSettings.Favorites.SCREEN, 1);
-                values.put(LauncherSettings.Favorites.CELLX, 1);
-                values.put(LauncherSettings.Favorites.CELLY, 0);
-                values.put(LauncherSettings.Favorites.SPANX, 2);
-                values.put(LauncherSettings.Favorites.SPANY, 2);
-                values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
+
+                values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_WIDGET_CLOCK);
+                values.put(Favorites.SPANX, 2);
+                values.put(Favorites.SPANY, 2);
+                values.put(Favorites.APPWIDGET_ID, appWidgetId);
                 db.insert(TABLE_FAVORITES, null, values);
-                
+
                 allocatedAppWidgets = true;
             } catch (RuntimeException ex) {
                 Log.e(LOG_TAG, "Problem allocating appWidgetId", ex);
@@ -563,8 +561,8 @@
             if (allocatedAppWidgets) {
                 launchAppWidgetBinder(bindSources, bindTargets);
             }
-            
-            return i;
+
+            return allocatedAppWidgets;
         }
     }
 
diff --git a/src/com/android/launcher/LiveFolder.java b/src/com/android/launcher/LiveFolder.java
index 5d727f8..44a283e 100644
--- a/src/com/android/launcher/LiveFolder.java
+++ b/src/com/android/launcher/LiveFolder.java
@@ -90,7 +90,13 @@
         if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
             mLoadingTask.cancel(true);
         }
-        ((LiveFolderAdapter) mContent.getAdapter()).cleanup();
+
+        // The adapter can be null if onClose() is called before FolderLoadingTask
+        // is done querying the provider
+        final LiveFolderAdapter adapter = (LiveFolderAdapter) mContent.getAdapter();
+        if (adapter != null) {
+            adapter.cleanup();
+        }
     }
 
     static class FolderLoadingTask extends AsyncTask<LiveFolderInfo, Void, Cursor> {
diff --git a/src/com/android/launcher/Workspace.java b/src/com/android/launcher/Workspace.java
index bc5347e..359767a 100644
--- a/src/com/android/launcher/Workspace.java
+++ b/src/com/android/launcher/Workspace.java
@@ -26,6 +26,7 @@
 import android.graphics.RectF;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -34,6 +35,7 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.widget.Scroller;
+import android.widget.TextView;
 import android.os.Parcelable;
 import android.os.Parcel;
 
@@ -1240,7 +1242,41 @@
             }
         }
     }
-    
+
+    void updateShortcutsForPackage(String packageName) {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final CellLayout layout = (CellLayout) getChildAt(i);
+            int childCount = layout.getChildCount();
+            for (int j = 0; j < childCount; j++) {
+                final View view = layout.getChildAt(j);
+                Object tag = view.getTag();
+                if (tag instanceof ApplicationInfo) {
+                    ApplicationInfo info = (ApplicationInfo) tag;
+                    // We need to check for ACTION_MAIN otherwise getComponent() might
+                    // return null for some shortcuts (for instance, for shortcuts to
+                    // web pages.)
+                    final Intent intent = info.intent;
+                    final ComponentName name = intent.getComponent();
+                    if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
+                            Intent.ACTION_MAIN.equals(intent.getAction()) && name != null &&
+                            packageName.equals(name.getPackageName())) {
+
+                        final Drawable icon = Launcher.getModel().getApplicationInfoIcon(
+                                mLauncher.getPackageManager(), info);
+                        if (icon != null && icon != info.icon) {
+                            info.icon.setCallback(null);
+                            info.icon = Utilities.createIconThumbnail(icon, mContext);
+                            info.filtered = true;
+                            ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(null,
+                                    info.icon, null, null);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     // TODO: remove widgets when appwidgetmanager tells us they're gone
 //    void removeAppWidgetsForProvider() {
 //    }