Merge branch 'master' into honeycomb-release
diff --git a/res/layout-xlarge/all_apps_tabbed.xml b/res/layout-xlarge-land/all_apps_tabbed.xml
similarity index 88%
copy from res/layout-xlarge/all_apps_tabbed.xml
copy to res/layout-xlarge-land/all_apps_tabbed.xml
index 5aca954..4f573f8 100644
--- a/res/layout-xlarge/all_apps_tabbed.xml
+++ b/res/layout-xlarge-land/all_apps_tabbed.xml
@@ -38,7 +38,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 launcher:cellCountX="7"
-                launcher:cellCountY="4">
+                launcher:cellCountY="4"
+                launcher:pageLayoutPaddingTop="10dp"
+                launcher:pageLayoutPaddingBottom="15dp"
+                launcher:pageLayoutPaddingLeft="20dp"
+                launcher:pageLayoutPaddingRight="20dp">
             </com.android.launcher2.AllAppsPagedView>
         </FrameLayout>
     </LinearLayout>
diff --git a/res/layout-xlarge-land/customization_drawer.xml b/res/layout-xlarge-land/customization_drawer.xml
index 4fcf761..7ad9132 100644
--- a/res/layout-xlarge-land/customization_drawer.xml
+++ b/res/layout-xlarge-land/customization_drawer.xml
@@ -19,4 +19,10 @@
 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    launcher:widgetCellCountX="16" />
\ No newline at end of file
+    launcher:widgetCellCountX="16"
+    launcher:cellCountX="7"
+    launcher:cellCountY="4"
+    launcher:pageLayoutPaddingTop="10dp"
+    launcher:pageLayoutPaddingBottom="15dp"
+    launcher:pageLayoutPaddingLeft="20dp"
+    launcher:pageLayoutPaddingRight="20dp" />
\ No newline at end of file
diff --git a/res/layout-xlarge/all_apps_tabbed.xml b/res/layout-xlarge-port/all_apps_tabbed.xml
similarity index 88%
rename from res/layout-xlarge/all_apps_tabbed.xml
rename to res/layout-xlarge-port/all_apps_tabbed.xml
index 5aca954..2ff0447 100644
--- a/res/layout-xlarge/all_apps_tabbed.xml
+++ b/res/layout-xlarge-port/all_apps_tabbed.xml
@@ -38,7 +38,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 launcher:cellCountX="7"
-                launcher:cellCountY="4">
+                launcher:cellCountY="4"
+                launcher:pageLayoutPaddingTop="10dp"
+                launcher:pageLayoutPaddingBottom="10dp"
+                launcher:pageLayoutPaddingLeft="0dp"
+                launcher:pageLayoutPaddingRight="0dp">
             </com.android.launcher2.AllAppsPagedView>
         </FrameLayout>
     </LinearLayout>
diff --git a/res/layout-xlarge-port/customization_drawer.xml b/res/layout-xlarge-port/customization_drawer.xml
index 6e4bc4c..db264b2 100644
--- a/res/layout-xlarge-port/customization_drawer.xml
+++ b/res/layout-xlarge-port/customization_drawer.xml
@@ -19,4 +19,10 @@
 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    launcher:widgetCellCountX="12" />
\ No newline at end of file
+    launcher:widgetCellCountX="12"
+    launcher:cellCountX="7"
+    launcher:cellCountY="4"
+    launcher:pageLayoutPaddingTop="10dp"
+    launcher:pageLayoutPaddingBottom="15dp"
+    launcher:pageLayoutPaddingLeft="0dp"
+    launcher:pageLayoutPaddingRight="0dp" />
\ No newline at end of file
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index c091034..b127e1e 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurace..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgety"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Složky"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Zástupci"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapety"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Toto bude karta Tapety"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Vše"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikace"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Hry"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Stažené"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Název složky"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Přejmenovat složku"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"zápis nastavení a odkazů plochy"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Povoluje aplikaci změnit nastavení a odkazy plochy."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problém s načtením widgetu"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Toto je systémová aplikace a nelze ji odinstalovat."</string>
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 045b834..c3b069e 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurer ..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Mapper"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Genveje"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapeter"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dette er fanen for tapeter"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Programmer"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Spil"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Downloadet"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Mappenavn"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Omdøb mappe"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"skriv indstillinger og genveje for Start"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Tillader, at et program ændrer indstillingerne og genvejene i Start."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Der er problemer med indlæsning af widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Dette er et systemprogram, som ikke kan afinstalleres."</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index a3367d2..6b5401f 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurieren..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Ordner"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Verknüpfungen"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Hintergründe"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dies ist der Tab \"Hintergründe\""</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Anwendungen"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Spiele"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Heruntergeladen"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Ordnername"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Ordner umbenennen"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"Einstellungen und Shortcuts für Startseite schreiben"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Ermöglicht einer Anwendung, die Einstellungen und Shortcuts auf der Startseite zu ändern."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problem beim Laden des Widgets"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 609a193..9326a93 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Διαμόρφωση..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Γραφικά στοιχεία"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Φάκελοι"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Συντομεύσεις"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Ταπετσαρίες"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Αυτή θα είναι η καρτέλα ταπετσαριών"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Κάθε ηλικία"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Εφαρμογές"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Παιχνίδια"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Η λήψη ολοκληρώθηκε"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Όνομα φακέλου"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Μετονομασία φακέλου"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"εγγραφή ρυθμίσεων και συντομεύσεων αρχικής οθόνης"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Επιτρέπει σε μια εφαρμογή την αλλαγή των ρυθμίσεων και των συντομεύσεων στην αρχική οθόνη."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Παρουσιάστηκε πρόβλημα στη φόρτωση του γραφικού στοιχείου"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Αυτή είναι εφαρμογή του συστήματος και δεν είναι δυνατή η κατάργηση της εγκατάστασής της."</string>
 </resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 4f8b890..b4e65d0 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configurar..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Carpetas"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Accesos directos"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Papeles tapiz"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ésta será la pestaña para los papeles tapiz"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Todos"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Google Apps"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Juegos"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Descargado"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nombre de carpeta"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Cambiar nombre de carpeta"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"escribir configuración y accesos directos de la página principal"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Permite a una aplicación cambiar la configuración y los accesos directos de la página principal."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problema al cargar el widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Esta es una aplicación de sistema y no puede desinstalarse."</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f6c5cf7..ecbe8af 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configurar..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Carpetas"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Accesos directos"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Fondos de pantalla"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Será la carpeta de fondos de pantalla."</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Todas las aplicaciones"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicaciones"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Juegos"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Descargadas"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nombre de carpeta"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Cambiar nombre de carpeta"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"escribir información de accesos directos y de configuración del escritorio"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Permite que una aplicación modifique la configuración y los accesos directos de la página de inicio."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problema al cargar el widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Se trata de una aplicación del sistema y no se puede desinstalar."</string>
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f1339fd..c6d530d 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configurer..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Dossiers"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Raccourcis"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Fonds d\'écran"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Onglet des fonds d\'écran"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Toutes"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Applications"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Jeux"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Téléchargées"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nom du dossier"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Renommer le dossier"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"Enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Permet à une application de modifier les paramètres et les raccourcis de la page d\'accueil."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problème lors du chargement du widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Il s\'agit d\'une application système que vous ne pouvez pas désinstaller."</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index fa2624b..f25156a 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configura..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widget"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Cartelle"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Scorciatorie"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Sfondi"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Questa sarà la scheda degli sfondi"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Tutte"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Applicazioni"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Giochi"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Scaricate"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nome cartella"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Rinomina cartella"</string>
@@ -74,7 +75,7 @@
     <skip />
     <!-- no translation found for cab_selection_text (8712157849499378915) -->
     <skip />
-    <string name="permlab_install_shortcut" msgid="1201690825493376489">"aggiungere scorciatorie"</string>
+    <string name="permlab_install_shortcut" msgid="1201690825493376489">"aggiungere scorciatoie"</string>
     <string name="permdesc_install_shortcut" msgid="7429365847558984148">"Consente a un\'applicazione di aggiungere scorciatoie automaticamente."</string>
     <string name="permlab_uninstall_shortcut" msgid="7696645932555926449">"eliminare scorciatoie"</string>
     <string name="permdesc_uninstall_shortcut" msgid="959972195916090900">"Consente a un\'applicazione di rimuovere scorciatoie automaticamente."</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"creare impostazioni e scorciatoie in Home"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Consente a un\'applicazione di modificare le impostazioni e le scorciatoie in Home."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Errore durante il caricamento del widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Questa è un\'applicazione di sistema e non può essere disinstallata."</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 09b23b7..98f042b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"設定..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"ウィジェット"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"フォルダ"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"ショートカット"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"壁紙"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"ここが壁紙タブになります"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"すべて"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"アプリ"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"ゲーム"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"ダウンロード済み"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"フォルダ名"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"フォルダ名を変更"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"ホームの設定とショートカットの書き込み"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"ホームの設定とショートカットの変更をアプリケーションに許可します。"</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"ウィジェットを表示できません"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"このシステムアプリケーションはアンインストールできません。"</string>
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index b943f1c..5213326 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"구성..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"위젯"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"폴더"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"바로가기"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"배경화면"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"배경화면 탭이 됩니다."</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"모두"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"애플리케이션"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"게임"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"다운로드앱"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"폴더 이름"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"폴더 이름 바꾸기"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"홈 설정 및 바로가기 쓰기"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"애플리케이션이 홈에 있는 설정 및 바로가기를 변경할 수 있도록 합니다."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"위젯을 로드하는 중 문제가 발생했습니다."</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"시스템 애플리케이션은 제거할 수 없습니다."</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 74ace88..0d24eb9 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurer"</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Moduler"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Mapper"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Snarveier"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Bakgrunner"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dette er nå bakgrunnsfanen"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Programmer"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Spill"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Nedlastet"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Mappenavn"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Gi nytt navn til mappe"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"skrive skrivebordsinnstillinger og -snarveier"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Lar applikasjonen endre innstillinger og snarveier på skrivebordet."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problem under lasting av gadget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Dette er et systemprogram og kan ikke avinstalleres."</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 42608e0..5a2a269 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configureren..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Mappen"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Sneltoetsen"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Achtergronden"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dit wordt het tabblad \'Achtergronden\'"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Toepassingen"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Games"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Gedownload"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Mapnaam"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Naam van map wijzigen"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"instellingen en snelkoppelingen voor de startpagina schrijven"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Probleem bij het laden van widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Dit is een systeemtoepassing die niet kan worden verwijderd."</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index ea51842..0c8e91b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfiguruj..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widżety"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Foldery"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Skróty"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapety"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"To będzie karta tapet"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Wszystkie"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikacje"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Gry"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Pobrane"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nazwa folderu"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Zmień nazwę folderu"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"zapisywanie ustawień i skrótów strony głównej"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Umożliwia aplikacji zmianę ustawień i skrótów strony głównej."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problem podczas ładowania widżetu"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"To jest aplikacja systemowa i nie można jej odinstalować."</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index b2d6c65..cdff3bf 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configurar..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Pastas"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Atalhos"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Imagens de fundo"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Isto será o separador de imagens de fundo"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Todas"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicações"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Jogos"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Transferidas"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nome da pasta"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Mudar o nome da pasta"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"escrever definições e atalhos do ecrã principal"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Permite que uma aplicação altere as definições e os atalhos do ecrã principal."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Erro ao carregar o widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"É uma aplicação de sistema e não pode ser desinstalada."</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index f3a7757..bdebb87 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Configurar..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Pastas"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Atalhos"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Papéis de parede"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Esta será a guia de papéis de parede"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Todos"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicativos"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Jogos"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Download concluído"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Nome da pasta"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Renomear pasta"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"gravar configurações e atalhos da Página inicial"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Permite que um aplicativo altere as configurações e atalhos na Página inicial."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Problema ao carregar o widget"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Este é um aplicativo do sistema e não pode ser desinstalado."</string>
 </resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 90a156b..0e4e4da 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -31,10 +31,12 @@
     <skip />
     <!-- no translation found for folders_tab_label (1145293785541489736) -->
     <skip />
-    <!-- no translation found for shortcuts_tab_label (3312788893569416806) -->
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
     <skip />
     <!-- no translation found for wallpapers_tab_label (1617804870364119879) -->
     <skip />
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <!-- no translation found for wallpapers_temp_tab_text (1660218201190495279) -->
     <skip />
     <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
@@ -45,6 +47,8 @@
     <skip />
     <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
     <skip />
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
+    <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Num da l\'ordinatur"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Renumnar l\'ordinatur"</string>
     <string name="rename_action" msgid="6016003384693240896">"OK"</string>
@@ -60,9 +64,9 @@
     <string name="add_clock" msgid="2337943840175865746">"Ura"</string>
     <string name="add_photo_frame" msgid="3154058437359487954">"Rom da maletgs"</string>
     <string name="out_of_space" msgid="8365249326091984698">"Nagin spazi liber sin il visur da partenza."</string>
-    <string name="shortcut_installed" msgid="7071557296331322355">"Creà ina scursanida \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
-    <string name="shortcut_uninstalled" msgid="2129499669449749995">"La scursanida \"<xliff:g id="NAME">%s</xliff:g>\" è vegnida stizzada."</string>
-    <string name="shortcut_duplicate" msgid="4757756326465060694">"La scursanida \"<xliff:g id="NAME">%s</xliff:g>\" exista gia."</string>
+    <string name="shortcut_installed" msgid="7071557296331322355">"\"Creà ina scursanida \"\"<xliff:g id="NAME">%s</xliff:g>\"\".\""</string>
+    <string name="shortcut_uninstalled" msgid="2129499669449749995">"\"La scursanida \"\"<xliff:g id="NAME">%s</xliff:g>\"\" è vegnida stizzada.\""</string>
+    <string name="shortcut_duplicate" msgid="4757756326465060694">"\"La scursanida \"\"<xliff:g id="NAME">%s</xliff:g>\"\" exista gia.\""</string>
     <string name="title_select_shortcut" msgid="2858897527672831763">"Tscherner ina cumbinaziun da tastas"</string>
     <string name="title_select_live_folder" msgid="3753447798805166749">"Tscherner l\'ordinatur"</string>
     <string name="all_apps_button_label" msgid="3953036962111614813">"Tut las applicaziuns"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 486c6d4..bb87445 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Настроить..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Виджеты"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Папки"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Ярлыки"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Обои"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Это будет вкладка обоев"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Все"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Приложения"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Игры"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Загруженные"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Название папки"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Переименовать папку"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"изменять настройки и ярлыки главного экрана"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Позволяет приложению изменять настройки и ярлыки на главном экране."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Не удалось загрузить виджет"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Это системное приложение. Удалить его невозможно."</string>
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 09258a9..be6ee7f 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurera..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widgetar"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Mappar"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Genvägar"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Bakgrundsbilder"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Det här kommer att vara fliken för bakgrundsbilder"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Alla"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Program"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Spel"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Hämtade"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Mappnamn"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Byt namn på mapp"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"skriva inställningar och genvägar för startsidan"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Tillåter att ett program ändrar inställningar och genvägar på startsidan."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Det gick inte att läsa in widgeten"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Det här är ett systemprogram och kan inte avinstalleras."</string>
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index e6922a5..59c816d 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"Yapılandır..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"Widget\'lar"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"Klasörler"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"Kısayollar"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"Duvar Kağıtları"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Bu duvar kağıdı sekmesi olacaktır"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"Tümü"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"Uygulamalar"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"Oyunlar"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"İndirilenler"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"Klasör adı"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"Klasörü yeniden adlandır"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"Ana Sayfa ayarlarını ve kısayollarını yaz"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"Bir uygulamaya Ana Sayfadaki ayarları ve kısayolları değiştirme izni verir."</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"Widget yüklenirken sorun oluştu"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"Bu bir sistem uygulamasıdır ve kaldırılamaz."</string>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index b1508dd..58f6178 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"配置..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"窗口小部件"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"文件夹"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"快捷方式"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"壁纸"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"这将会成为壁纸标签"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"全部"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"应用程序"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"游戏"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"已下载"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"文件夹名称"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"重命名文件夹"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"写入主屏幕的设置和快捷方式"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"允许应用程序更改主屏幕的设置和快捷方式。"</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"载入窗口小部件时出现问题"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"这是系统应用程序,无法卸载。"</string>
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 18cbfcb..a7cd098 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -29,16 +29,17 @@
     <string name="configure_wallpaper" msgid="2820186271419674623">"設定..."</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"小工具"</string>
     <string name="folders_tab_label" msgid="1145293785541489736">"資料夾"</string>
-    <string name="shortcuts_tab_label" msgid="3312788893569416806">"快速鍵"</string>
+    <!-- no translation found for shortcuts_tab_label (8640731503933155644) -->
+    <skip />
     <string name="wallpapers_tab_label" msgid="1617804870364119879">"桌布"</string>
+    <!-- no translation found for applications_tab_label (9046797126882613707) -->
+    <skip />
     <string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"桌布標籤保留位"</string>
-    <!-- no translation found for all_apps_tab_all (2942727589595027258) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_apps (5468972551904071712) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_games (1855736784923494918) -->
-    <skip />
-    <!-- no translation found for all_apps_tab_downloaded (2300935549064726963) -->
+    <string name="all_apps_tab_all" msgid="2942727589595027258">"全部"</string>
+    <string name="all_apps_tab_apps" msgid="5468972551904071712">"應用程式"</string>
+    <string name="all_apps_tab_games" msgid="1855736784923494918">"遊戲"</string>
+    <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"下載內容"</string>
+    <!-- no translation found for widget_dims_format (412876472704567784) -->
     <skip />
     <string name="rename_folder_label" msgid="5646236631298452787">"資料夾名稱"</string>
     <string name="rename_folder_title" msgid="4544573104191526550">"重新命名資料夾"</string>
@@ -83,6 +84,5 @@
     <string name="permlab_write_settings" msgid="1360567537236705628">"寫入首頁設定和捷徑"</string>
     <string name="permdesc_write_settings" msgid="1098648778383349818">"允許應用程式變更首頁中的設定和捷徑。"</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"載入小工具時發生問題"</string>
-    <!-- no translation found for uninstall_system_app_text (7488523163288397451) -->
-    <skip />
+    <string name="uninstall_system_app_text" msgid="7488523163288397451">"這是系統應用程式,無法將其解除安裝。"</string>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 3ef26fb..bb1b85f 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -75,6 +75,11 @@
         <attr name="cellCountX" />
         <!-- The number of vertical cells in a page -->
         <attr name="cellCountY" />
+        <!-- The padding of the pages that are dynamically created per page -->
+        <attr name="pageLayoutPaddingTop" format="dimension" />
+        <attr name="pageLayoutPaddingBottom" format="dimension" />
+        <attr name="pageLayoutPaddingLeft" format="dimension" />
+        <attr name="pageLayoutPaddingRight" format="dimension" />
     </declare-styleable>
 
     <!-- CustomizePagedView specific attributes. These attributes are used to customize
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 00febfe..4d88a33 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -50,9 +50,11 @@
     <string name="folders_tab_label">Folders</string>
     <!--  Title of tab containing all possible shortcuts (eg Contacts, Bookmarks) that can be
           added to the home screen -->
-    <string name="shortcuts_tab_label">Shortcuts</string>
+    <string name="shortcuts_tab_label">More</string>
     <!--  Title of tab for configuring wallpapers -->
     <string name="wallpapers_tab_label">Wallpapers</string>
+    <!--  Title of tab for configuring applications -->
+    <string name="applications_tab_label">App Shortcuts</string>
     <!--  Placeholder text, will be removed -->
     <string name="wallpapers_temp_tab_text">This will be the wallpapers tab</string>
     <!--  Labels for the tabs in All Apps -->
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index a2a3793..3c39474 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -68,6 +68,10 @@
 
     private int mCellCountX;
     private int mCellCountY;
+    private int mPageLayoutPaddingTop;
+    private int mPageLayoutPaddingBottom;
+    private int mPageLayoutPaddingLeft;
+    private int mPageLayoutPaddingRight;
 
     private final LayoutInflater mInflater;
 
@@ -90,6 +94,14 @@
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, defStyle, 0);
         mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6);
         mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
+        mPageLayoutPaddingTop = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingTop, 10);
+        mPageLayoutPaddingBottom = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingBottom, 10);
+        mPageLayoutPaddingLeft = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingLeft, 10);
+        mPageLayoutPaddingRight = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingRight, 10);
         mInflater = LayoutInflater.from(context);
         a.recycle();
         setSoundEffectsEnabled(false);
@@ -354,6 +366,8 @@
         for (int i = curNumPages; i < numPages; ++i) {
             PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
             layout.setCellCount(mCellCountX, mCellCountY);
+            layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+                    mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
             addView(layout);
         }
 
@@ -497,4 +511,8 @@
     @Override
     public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {}
+
+    public boolean isDropEnabled() {
+        return true;
+    }
 }
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 0e342a7..cb45b3a 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -110,6 +110,10 @@
         }
     }
 
+    public boolean isDropEnabled() {
+        return true;
+    }
+
     public void onDragEnd() {
         if (mActive) {
             mActive = false;
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 4d1c299..62e32d2 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -40,8 +40,6 @@
 public class CellLayout extends ViewGroup {
     static final String TAG = "CellLayout";
 
-    private boolean mPortrait;
-
     private int mCellWidth;
     private int mCellHeight;
 
@@ -90,9 +88,6 @@
     // When a drag operation is in progress, holds the nearest cell to the touch point
     private final int[] mDragCell = new int[2];
 
-    private boolean mDirtyTag;
-    private boolean mLastDownOnOccupiedCell = false;
-
     private final WallpaperManager mWallpaperManager;
 
     public CellLayout(Context context) {
@@ -135,6 +130,7 @@
 
         mCountX = LauncherModel.getCellCountX();
         mCountY = LauncherModel.getCellCountY();
+        mOccupied = new boolean[mCountX][mCountY];
 
         a.recycle();
 
@@ -214,15 +210,60 @@
             // We might be in the middle or end of shrinking/fading to a dimmed view
             // Make sure this view's alpha is set the same as all the rest of the views
             child.setAlpha(getAlpha());
-
             addView(child, index, lp);
 
+            markCellsAsOccupiedForView(child);
+
             return true;
         }
         return false;
     }
 
     @Override
+    public void removeAllViews() {
+        clearOccupiedCells();
+    }
+
+    @Override
+    public void removeAllViewsInLayout() {
+        clearOccupiedCells();
+    }
+
+    @Override
+    public void removeView(View view) {
+        markCellsAsUnoccupiedForView(view);
+        super.removeView(view);
+    }
+
+    @Override
+    public void removeViewAt(int index) {
+        markCellsAsUnoccupiedForView(getChildAt(index));
+        super.removeViewAt(index);
+    }
+
+    @Override
+    public void removeViewInLayout(View view) {
+        markCellsAsUnoccupiedForView(view);
+        super.removeViewInLayout(view);
+    }
+
+    @Override
+    public void removeViews(int start, int count) {
+        for (int i = start; i < start + count; i++) {
+            markCellsAsUnoccupiedForView(getChildAt(i));
+        }
+        super.removeViews(start, count);
+    }
+
+    @Override
+    public void removeViewsInLayout(int start, int count) {
+        for (int i = start; i < start + count; i++) {
+            markCellsAsUnoccupiedForView(getChildAt(i));
+        }
+        super.removeViewsInLayout(start, count);
+    }
+
+    @Override
     public void requestChildFocus(View child, View focused) {
         super.requestChildFocus(child, focused);
         if (child != null) {
@@ -258,45 +299,24 @@
                     cellInfo.cellY = lp.cellY;
                     cellInfo.spanX = lp.cellHSpan;
                     cellInfo.spanY = lp.cellVSpan;
-                    cellInfo.intersectX = lp.cellX;
-                    cellInfo.intersectY = lp.cellY;
                     cellInfo.valid = true;
                     found = true;
-                    mDirtyTag = false;
                     break;
                 }
             }
         }
 
-        mLastDownOnOccupiedCell = found;
-
         if (!found) {
             final int cellXY[] = mTmpCellXY;
             pointToCellExact(x, y, cellXY);
 
-            final boolean portrait = mPortrait;
-            final int xCount = mCountX;
-            final int yCount = mCountY;
-
-            final boolean[][] occupied = mOccupied;
-            findOccupiedCells(xCount, yCount, occupied, null, true);
-
             cellInfo.cell = null;
             cellInfo.cellX = cellXY[0];
             cellInfo.cellY = cellXY[1];
             cellInfo.spanX = 1;
             cellInfo.spanY = 1;
-            cellInfo.intersectX = cellXY[0];
-            cellInfo.intersectY = cellXY[1];
-            cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
-                    cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
-
-            // Instead of finding the interesting vacant cells here, wait until a
-            // caller invokes getTag() to retrieve the result. Finding the vacant
-            // cells is a bit expensive and can generate many new objects, it's
-            // therefore better to defer it until we know we actually need it.
-
-            mDirtyTag = true;
+            cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < mCountX &&
+                    cellXY[1] < mCountY && !mOccupied[cellXY[0]][cellXY[1]];
         }
         setTag(cellInfo);
     }
@@ -319,7 +339,6 @@
             cellInfo.spanX = 0;
             cellInfo.spanY = 0;
             cellInfo.valid = false;
-            mDirtyTag = false;
             setTag(cellInfo);
         }
 
@@ -328,31 +347,7 @@
 
     @Override
     public CellInfo getTag() {
-        final CellInfo info = (CellInfo) super.getTag();
-        if (mDirtyTag && info.valid) {
-            final int xCount = mCountX;
-            final int yCount = mCountY;
-
-            final boolean[][] occupied = mOccupied;
-            findOccupiedCells(xCount, yCount, occupied, null, true);
-
-            info.updateOccupiedCells(occupied, mCountX, mCountY);
-
-            mDirtyTag = false;
-        }
-        return info;
-    }
-
-    /**
-     * Check if the column 'x' is empty from rows 'top' to 'bottom', inclusive.
-     */
-    private static boolean isColumnEmpty(int x, int top, int bottom, boolean[][] occupied) {
-        for (int y = top; y <= bottom; y++) {
-            if (occupied[x][y]) {
-                return false;
-            }
-        }
-        return true;
+        return (CellInfo) super.getTag();
     }
 
     /**
@@ -367,42 +362,6 @@
         return true;
     }
 
-    CellInfo updateOccupiedCells(boolean[] occupiedCells, View ignoreView) {
-        final int xCount = mCountX;
-        final int yCount = mCountY;
-
-        boolean[][] occupied = mOccupied;
-
-        if (occupiedCells != null) {
-            for (int y = 0; y < yCount; y++) {
-                for (int x = 0; x < xCount; x++) {
-                    occupied[x][y] = occupiedCells[y * xCount + x];
-                }
-            }
-        } else {
-            findOccupiedCells(xCount, yCount, occupied, ignoreView, true);
-        }
-
-        CellInfo cellInfo = new CellInfo();
-
-        cellInfo.cellX = -1;
-        cellInfo.cellY = -1;
-        cellInfo.intersectX = -1;
-        cellInfo.intersectY = -1;
-        cellInfo.spanY = 0;
-        cellInfo.spanX = 0;
-        cellInfo.screen = mCellInfo.screen;
-
-        cellInfo.updateOccupiedCells(occupied, mCountX, mCountY);
-
-        cellInfo.valid = cellInfo.existsEmptyCell();
-
-        // Assume the caller will perform their own cell searching, otherwise we
-        // risk causing an unnecessary rebuild after findCellForSpan()
-
-        return cellInfo;
-    }
-
     /**
      * Given a point, return the cell that strictly encloses that point
      * @param x X coordinate of the point
@@ -492,19 +451,13 @@
         final int cellWidth = mCellWidth;
         final int cellHeight = mCellHeight;
 
-        if (mOccupied == null) {
-            mOccupied = new boolean[mCountX][mCountY];
-        }
-
         int numWidthGaps = mCountX - 1;
         int numHeightGaps = mCountY - 1;
 
-        int vSpaceLeft = heightSpecSize - mTopPadding
-                - mBottomPadding - (cellHeight * mCountY);
+        int vSpaceLeft = heightSpecSize - mTopPadding - mBottomPadding - (cellHeight * mCountY);
         mHeightGap = vSpaceLeft / numHeightGaps;
 
-        int hSpaceLeft = widthSpecSize - mLeftPadding
-                - mRightPadding - (cellWidth * mCountX);
+        int hSpaceLeft = widthSpecSize - mLeftPadding - mRightPadding - (cellWidth * mCountX);
         mWidthGap = hSpaceLeft / numWidthGaps;
 
         // center it around the min gaps
@@ -519,8 +472,7 @@
             lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
                     mLeftPadding, mTopPadding);
 
-            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
-                    MeasureSpec.EXACTLY);
+            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
             int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
                     MeasureSpec.EXACTLY);
 
@@ -621,13 +573,26 @@
         }
     }
 
-    private boolean isVacant(int originX, int originY, int spanX, int spanY) {
+    private boolean isVacantIgnoring(
+            int originX, int originY, int spanX, int spanY, View ignoreView) {
+        if (ignoreView != null) {
+            markCellsAsUnoccupiedForView(ignoreView);
+        }
+        boolean isVacant = true;
         for (int i = 0; i < spanY; i++) {
             if (!isRowEmpty(originY + i, originX, originX + spanX - 1, mOccupied)) {
-                return false;
+                isVacant = false;
+                break;
             }
         }
-        return true;
+        if (ignoreView != null) {
+            markCellsAsOccupiedForView(ignoreView);
+        }
+        return isVacant;
+    }
+
+    private boolean isVacant(int originX, int originY, int spanX, int spanY) {
+        return isVacantIgnoring(originX, originY, spanX, spanY, null);
     }
 
     public View getChildAt(int x, int y) {
@@ -687,7 +652,8 @@
         result[1] = Math.max(0, result[1]); // Snap to top
     }
 
-    void visualizeDropLocation(View view, int originX, int originY, int spanX, int spanY) {
+    void visualizeDropLocation(
+            View view, int originX, int originY, int spanX, int spanY, View draggedItem) {
         final int[] originCell = mDragCell;
         final int[] cellXY = mTmpCellXY;
         estimateDropCell(originX, originY, spanX, spanY, cellXY);
@@ -709,12 +675,8 @@
             bottomRight[0] += mCellWidth;
             bottomRight[1] += mCellHeight;
 
-            final int countX = mCountX;
-            final int countY = mCountY;
-            // TODO: It's not necessary to do this every time, but it's not especially expensive
-            findOccupiedCells(countX, countY, mOccupied, view, false);
-
-            boolean vacant = isVacant(originCell[0], originCell[1], spanX, spanY);
+            boolean vacant =
+                isVacantIgnoring(originCell[0], originCell[1], spanX, spanY, draggedItem);
             mDragRectDrawable = vacant ? mVacantDrawable : mOccupiedDrawable;
 
             // mDragRect will be rendered in onDraw()
@@ -736,8 +698,7 @@
      * @return The X, Y cell of a vacant area that can contain this object,
      *         nearest the requested location.
      */
-    int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY,
-            CellInfo vacantCells, int[] recycle) {
+    int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY, int[] recycle) {
 
         // Keep track of best-scoring drop area
         final int[] bestXY = recycle != null ? recycle : new int[2];
@@ -777,10 +738,129 @@
         }
     }
 
+    boolean existsEmptyCell() {
+        return findCellForSpan(null, 1, 1);
+    }
+
     /**
-     * Called when a drag and drop operation has finished (successfully or not).
+     * Finds the upper-left coordinate of the first rectangle in the grid that can
+     * hold a cell of the specified dimensions. If intersectX and intersectY are not -1,
+     * then this method will only return coordinates for rectangles that contain the cell
+     * (intersectX, intersectY)
+     *
+     * @param cellXY The array that will contain the position of a vacant cell if such a cell
+     *               can be found.
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     *
+     * @return True if a vacant cell of the specified dimension was found, false otherwise.
      */
-    void onDragComplete() {
+    boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
+        return findCellForSpanThatIntersectsIgnoring(cellXY, spanX, spanY, -1, -1, null);
+    }
+
+    /**
+     * Like above, but ignores any cells occupied by the item "ignoreView"
+     *
+     * @param cellXY The array that will contain the position of a vacant cell if such a cell
+     *               can be found.
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     * @param ignoreView The home screen item we should treat as not occupying any space
+     * @return
+     */
+    boolean findCellForSpanIgnoring(int[] cellXY, int spanX, int spanY, View ignoreView) {
+        return findCellForSpanThatIntersectsIgnoring(cellXY, spanX, spanY, -1, -1, ignoreView);
+    }
+
+    /**
+     * Like above, but if intersectX and intersectY are not -1, then this method will try to
+     * return coordinates for rectangles that contain the cell [intersectX, intersectY]
+     *
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     * @param ignoreView The home screen item we should treat as not occupying any space
+     * @param intersectX The X coordinate of the cell that we should try to overlap
+     * @param intersectX The Y coordinate of the cell that we should try to overlap
+     *
+     * @return True if a vacant cell of the specified dimension was found, false otherwise.
+     */
+    boolean findCellForSpanThatIntersects(int[] cellXY, int spanX, int spanY,
+            int intersectX, int intersectY) {
+        return findCellForSpanThatIntersectsIgnoring(
+                cellXY, spanX, spanY, intersectX, intersectY, null);
+    }
+
+    /**
+     * The superset of the above two methods
+     */
+    boolean findCellForSpanThatIntersectsIgnoring(int[] cellXY, int spanX, int spanY,
+            int intersectX, int intersectY, View ignoreView) {
+        if (ignoreView != null) {
+            markCellsAsUnoccupiedForView(ignoreView);
+        }
+
+        boolean foundCell = false;
+        while (true) {
+            int startX = 0;
+            if (intersectX >= 0) {
+                startX = Math.max(startX, intersectX - (spanX - 1));
+            }
+            int endX = mCountX - (spanX - 1);
+            if (intersectX >= 0) {
+                endX = Math.min(endX, intersectX + (spanX - 1) + (spanX == 1 ? 1 : 0));
+            }
+            int startY = 0;
+            if (intersectY >= 0) {
+                startY = Math.max(startY, intersectY - (spanY - 1));
+            }
+            int endY = mCountY - (spanY - 1);
+            if (intersectY >= 0) {
+                endY = Math.min(endY, intersectY + (spanY - 1) + (spanY == 1 ? 1 : 0));
+            }
+
+            for (int x = startX; x < endX; x++) {
+                inner:
+                for (int y = startY; y < endY; y++) {
+                    for (int i = 0; i < spanX; i++) {
+                        for (int j = 0; j < spanY; j++) {
+                            if (mOccupied[x + i][y + j]) {
+                                // small optimization: we can skip to below the row we just found
+                                // an occupied cell
+                                y += j;
+                                continue inner;
+                            }
+                        }
+                    }
+                    if (cellXY != null) {
+                        cellXY[0] = x;
+                        cellXY[1] = y;
+                    }
+                    foundCell = true;
+                    break;
+                }
+            }
+            if (intersectX == -1 && intersectY == -1) {
+                break;
+            } else {
+                // if we failed to find anything, try again but without any requirements of
+                // intersecting
+                intersectX = -1;
+                intersectY = -1;
+                continue;
+            }
+        }
+
+        if (ignoreView != null) {
+            markCellsAsOccupiedForView(ignoreView);
+        }
+        return foundCell;
+    }
+
+    /**
+     * Called when drag has left this CellLayout or has been completed (successfully or not)
+     */
+    void onDragExit() {
         // Invalidate the drag data
         mDragCell[0] = -1;
         mDragCell[1] = -1;
@@ -803,14 +883,14 @@
             mDragRect.setEmpty();
             child.requestLayout();
         }
-        onDragComplete();
+        onDragExit();
     }
 
     void onDropAborted(View child) {
         if (child != null) {
             ((LayoutParams) child.getLayoutParams()).isDragging = false;
         }
-        onDragComplete();
+        onDragExit();
     }
 
     /**
@@ -889,13 +969,8 @@
      * @return True if a vacant cell was found
      */
     public boolean getVacantCell(int[] vacant, int spanX, int spanY) {
-        final int xCount = mCountX;
-        final int yCount = mCountY;
-        final boolean[][] occupied = mOccupied;
 
-        findOccupiedCells(xCount, yCount, occupied, null, true);
-
-        return findVacantCell(vacant, spanX, spanY, xCount, yCount, occupied);
+        return findVacantCell(vacant, spanX, spanY, mCountX, mCountY, mOccupied);
     }
 
     static boolean findVacantCell(int[] vacant, int spanX, int spanY,
@@ -930,8 +1005,6 @@
         final int yCount = mCountY;
         final boolean[][] occupied = mOccupied;
 
-        findOccupiedCells(xCount, yCount, occupied, null, true);
-
         final boolean[] flat = new boolean[xCount * yCount];
         for (int y = 0; y < yCount; y++) {
             for (int x = 0; x < xCount; x++) {
@@ -942,32 +1015,34 @@
         return flat;
     }
 
-    /**
-     * Update the array of occupied cells.
-     * @param ignoreView If non-null, the space occupied by this View is treated as vacant
-     * @param ignoreFolders If true, a cell occupied by a Folder is treated as vacant
-     */
-    private void findOccupiedCells(
-            int xCount, int yCount, boolean[][] occupied, View ignoreView, boolean ignoreFolders) {
-
-        for (int x = 0; x < xCount; x++) {
-            for (int y = 0; y < yCount; y++) {
-                occupied[x][y] = false;
+    private void clearOccupiedCells() {
+        for (int x = 0; x < mCountX; x++) {
+            for (int y = 0; y < mCountY; y++) {
+                mOccupied[x][y] = false;
             }
         }
+    }
 
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            View child = getChildAt(i);
-            if ((ignoreFolders && child instanceof Folder) || child.equals(ignoreView)) {
-                continue;
-            }
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+    public void onMove(View view, int newCellX, int newCellY) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsAsUnoccupiedForView(view);
+        markCellsForView(newCellX, newCellY, lp.cellHSpan, lp.cellVSpan, true);
+    }
 
-            for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan && x < xCount; x++) {
-                for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan && y < yCount; y++) {
-                    occupied[x][y] = true;
-                }
+    private void markCellsAsOccupiedForView(View view) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true);
+    }
+
+    private void markCellsAsUnoccupiedForView(View view) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false);
+    }
+
+    private void markCellsForView(int cellX, int cellY, int spanX, int spanY, boolean value) {
+        for (int x = cellX; x < cellX + spanX && x < mCountX; x++) {
+            for (int y = cellY; y < cellY + spanY && y < mCountY; y++) {
+                mOccupied[x][y] = value;
             }
         }
     }
@@ -1087,117 +1162,25 @@
         }
     }
 
+    // This class stores info for two purposes:
+    // 1. When dragging items (mDragInfo in Workspace), we store the View, its cellX & cellY,
+    //    its spanX, spanY, and the screen it is on
+    // 2. When long clicking on an empty cell in a CellLayout, we save information about the
+    //    cellX and cellY coordinates and which page was clicked. We then set this as a tag on
+    //    the CellLayout that was long clicked
     static final class CellInfo implements ContextMenu.ContextMenuInfo {
-        private boolean[][] mOccupied;
-        private int mCountX;
-        private int mCountY;
         View cell;
         int cellX = -1;
         int cellY = -1;
-        // intersectX and intersectY constrain the results of findCellForSpan; any empty space
-        // it results must include this point (unless intersectX and intersectY are -1)
-        int intersectX = -1;
-        int intersectY = -1;
         int spanX;
         int spanY;
         int screen;
         boolean valid;
 
-        void updateOccupiedCells(boolean[][] occupied, int xCount, int yCount) {
-            mOccupied = occupied.clone();
-            mCountX = xCount;
-            mCountY = yCount;
-        }
-
-        void updateOccupiedCells(boolean[] occupied, int xCount, int yCount) {
-            if (mOccupied == null || mCountX != xCount || mCountY != yCount) {
-                mOccupied = new boolean[xCount][yCount];
-            }
-            mCountX = xCount;
-            mCountY = yCount;
-            for (int y = 0; y < yCount; y++) {
-                for (int x = 0; x < xCount; x++) {
-                    mOccupied[x][y] = occupied[y * xCount + x];
-                }
-            }
-        }
-
-        boolean existsEmptyCell() {
-            return findCellForSpan(null, 1, 1);
-        }
-        /**
-         * Finds the upper-left coordinate of the first rectangle in the grid that can
-         * hold a cell of the specified dimensions. If intersectX and intersectY are not -1,
-         * then this method will only return coordinates for rectangles that contain the cell
-         * (intersectX, intersectY)
-         *
-         * @param cellXY The array that will contain the position of a vacant cell if such a cell
-         *               can be found.
-         * @param spanX The horizontal span of the cell we want to find.
-         * @param spanY The vertical span of the cell we want to find.
-         *
-         * @return True if a vacant cell of the specified dimension was found, false otherwise.
-         */
-        boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
-            // return the span represented by the CellInfo only there is no view there
-            //   (this.cell == null) and there is enough space
-
-            if (this.cell == null && this.spanX >= spanX && this.spanY >= spanY) {
-                if (cellXY != null) {
-                    cellXY[0] = cellX;
-                    cellXY[1] = cellY;
-                }
-                return true;
-            }
-
-            int startX = 0;
-            if (intersectX >= 0) {
-                startX = Math.max(startX, intersectX - (spanX - 1));
-            }
-            int endX = mCountX - (spanX - 1);
-            if (intersectX >= 0) {
-                endX = Math.min(endX, intersectX + (spanX - 1));
-            }
-            int startY = 0;
-            if (intersectY >= 0) {
-                startY = Math.max(startY, intersectY - (spanY - 1));
-            }
-            int endY = mCountY - (spanY - 1);
-            if (intersectY >= 0) {
-                endY = Math.min(endY, intersectY + (spanY - 1));
-            }
-
-            for (int x = startX; x < endX; x++) {
-                inner:
-                for (int y = startY; y < endY; y++) {
-                    for (int i = 0; i < spanX; i++) {
-                        for (int j = 0; j < spanY; j++) {
-                            if (mOccupied[x + i][y + j]) {
-                                // small optimization: we can skip to below the row we just found
-                                // an occupied cell
-                                y += j;
-                                continue inner;
-                            }
-                        }
-                    }
-                    if (cellXY != null) {
-                        cellXY[0] = x;
-                        cellXY[1] = y;
-                    }
-                    return true;
-                }
-            }
-            return false;
-        }
-
         @Override
         public String toString() {
             return "Cell[view=" + (cell == null ? "null" : cell.getClass())
                     + ", x=" + cellX + ", y=" + cellY + "]";
         }
     }
-
-    public boolean lastDownOnOccupiedCell() {
-        return mLastDownOnOccupiedCell;
-    }
 }
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 8fb3025..79b3e6f 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -16,10 +16,7 @@
 
 package com.android.launcher2;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import com.android.launcher.R;
 
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -28,13 +25,12 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.Bitmap.Config;
 import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
 import android.provider.LiveFolders;
@@ -44,12 +40,14 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.launcher.R;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 public class CustomizePagedView extends PagedView
     implements View.OnLongClickListener, View.OnClickListener,
@@ -59,7 +57,8 @@
         WidgetCustomization,
         FolderCustomization,
         ShortcutCustomization,
-        WallpaperCustomization
+        WallpaperCustomization,
+        ApplicationCustomization
     }
 
     /**
@@ -109,9 +108,14 @@
     private List<ResolveInfo> mFolderList;
     private List<ResolveInfo> mShortcutList;
     private List<ResolveInfo> mWallpaperList;
+    private List<ApplicationInfo> mApps;
 
-    private static final int sCellCountX = 8;
-    private static final int sCellCountY = 4;
+    private int mCellCountX;
+    private int mCellCountY;
+    private int mPageLayoutPaddingTop;
+    private int mPageLayoutPaddingBottom;
+    private int mPageLayoutPaddingLeft;
+    private int mPageLayoutPaddingRight;
     private static final int sMinWidgetCellHSpan = 2;
     private static final int sMaxWidgetCellHSpan = 4;
 
@@ -132,14 +136,27 @@
     public CustomizePagedView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView,
+        TypedArray a;
+        a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView,
                 defStyle, 0);
+        mMaxWidgetsCellHSpan = a.getInt(R.styleable.CustomizePagedView_widgetCellCountX, 8);
+        a.recycle();
+        a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, defStyle, 0);
+        mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 7);
+        mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
+        mPageLayoutPaddingTop = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingTop, 10);
+        mPageLayoutPaddingBottom = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingBottom, 10);
+        mPageLayoutPaddingLeft = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingLeft, 10);
+        mPageLayoutPaddingRight = a.getDimensionPixelSize(
+                R.styleable.PagedView_pageLayoutPaddingRight, 10);
+        a.recycle();
         mCustomizationType = CustomizationType.WidgetCustomization;
         mWidgetPages = new ArrayList<ArrayList<AppWidgetProviderInfo>>();
         mWorkspaceWidgetLayout = new PagedViewCellLayout(context);
         mInflater = LayoutInflater.from(context);
-        mMaxWidgetsCellHSpan = a.getInt(R.styleable.CustomizePagedView_widgetCellCountX, 8);
-        a.recycle();
 
         setVisibility(View.GONE);
         setSoundEffectsEnabled(false);
@@ -152,6 +169,93 @@
         mPackageManager = context.getPackageManager();
     }
 
+    /**
+     * Sets the list of applications that launcher has loaded.
+     */
+    public void setApps(ArrayList<ApplicationInfo> list) {
+        mApps = list;
+        Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
+        mPageViewIconCache.clear();
+        invalidatePageData();
+    }
+
+    /**
+     * Convenience function to add new items to the set of applications that were previously loaded.
+     * Called by both updateApps() and setApps().
+     */
+    private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+        // we add it in place, in alphabetical order
+        final int count = list.size();
+        for (int i = 0; i < count; ++i) {
+            final ApplicationInfo info = list.get(i);
+            final int index = Collections.binarySearch(mApps, info, LauncherModel.APP_NAME_COMPARATOR);
+            if (index < 0) {
+                mApps.add(-(index + 1), info);
+            }
+        }
+    }
+
+    /**
+     * Adds new applications to the loaded list, and notifies the paged view to update itself.
+     */
+    public void addApps(ArrayList<ApplicationInfo> list) {
+        addAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+
+    /**
+     * Convenience function to remove items to the set of applications that were previously loaded.
+     * Called by both updateApps() and removeApps().
+     */
+    private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+        // loop through all the apps and remove apps that have the same component
+        final int length = list.size();
+        for (int i = 0; i < length; ++i) {
+            final ApplicationInfo info = list.get(i);
+            int removeIndex = findAppByComponent(mApps, info);
+            if (removeIndex > -1) {
+                mApps.remove(removeIndex);
+                mPageViewIconCache.removeOutline(info);
+            }
+        }
+    }
+
+    /**
+     * Removes applications from the loaded list, and notifies the paged view to update itself.
+     */
+    public void removeApps(ArrayList<ApplicationInfo> list) {
+        removeAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+
+    /**
+     * Updates a set of applications from the loaded list, and notifies the paged view to update
+     * itself.
+     */
+    public void updateApps(ArrayList<ApplicationInfo> list) {
+        // We remove and re-add the updated applications list because it's properties may have
+        // changed (ie. the title), and this will ensure that the items will be in their proper
+        // place in the list.
+        removeAppsWithoutInvalidate(list);
+        addAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+
+    /**
+     * Convenience function to find matching ApplicationInfos for removal.
+     */
+    private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
+        ComponentName removeComponent = item.intent.getComponent();
+        final int length = list.size();
+        for (int i = 0; i < length; ++i) {
+            ApplicationInfo info = list.get(i);
+            if (info.intent.getComponent().equals(removeComponent)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     public void update() {
         Context context = getContext();
 
@@ -248,6 +352,7 @@
         }
 
         final View animView = v;
+        PendingAddItemInfo createItemInfo = new PendingAddItemInfo();
         switch (mCustomizationType) {
         case WidgetCustomization:
             // Get the icon as the drag representation
@@ -259,58 +364,42 @@
             icon.draw(c);
 
             AppWidgetProviderInfo appWidgetInfo = (AppWidgetProviderInfo) v.getTag();
-            LauncherAppWidgetInfo dragInfo = new LauncherAppWidgetInfo(appWidgetInfo.provider);
-            dragInfo.minWidth = appWidgetInfo.minWidth;
-            dragInfo.minHeight = appWidgetInfo.minHeight;
-            mDragController.startDrag(v, b, this, dragInfo, DragController.DRAG_ACTION_COPY, null);
+            createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
+            createItemInfo.componentName = appWidgetInfo.provider;
+            mDragController.startDrag(v, b, this, createItemInfo, DragController.DRAG_ACTION_COPY, null);
 
             // Cleanup the icon
             b.recycle();
             return true;
         case FolderCustomization:
-            // animate some feedback to the long press
-            animateClickFeedback(v, new Runnable() {
-                @Override
-                public void run() {
-                    // add the folder
-                    ResolveInfo resolveInfo = (ResolveInfo) animView.getTag();
-                    Intent createFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
-                    if (resolveInfo.labelRes == R.string.group_folder) {
-                        // Create app shortcuts is a special built-in case of shortcuts
-                        createFolderIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
-                            getContext().getString(R.string.group_folder));
-                    } else {
-                        ComponentName name = new ComponentName(resolveInfo.activityInfo.packageName,
-                                resolveInfo.activityInfo.name);
-                        createFolderIntent.setComponent(name);
-                    }
-                    mLauncher.prepareAddItemFromHomeCustomizationDrawer();
-                    mLauncher.addLiveFolder(createFolderIntent);
-                }
-            });
+            ResolveInfo resolveInfo = (ResolveInfo) animView.getTag();
+            if (resolveInfo.labelRes == R.string.group_folder) {
+                UserFolderInfo folderInfo = new UserFolderInfo();
+                folderInfo.title = getResources().getText(R.string.folder_name);
+                mDragController.startDrag(
+                        v, this, folderInfo, DragController.DRAG_ACTION_COPY, null);
+            } else {
+                createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER;
+                createItemInfo.componentName = new ComponentName(
+                        resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
+                mDragController.startDrag(
+                        v, this, createItemInfo, DragController.DRAG_ACTION_COPY, null);
+            }
             return true;
         case ShortcutCustomization:
-            // animate some feedback to the long press
-            animateClickFeedback(v, new Runnable() {
-                @Override
-                public void run() {
-                    // add the shortcut
-                    ResolveInfo info = (ResolveInfo) animView.getTag();
-                    Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
-                    if (info.labelRes == R.string.group_applications) {
-                        // Create app shortcuts is a special built-in case of shortcuts
-                        createShortcutIntent.putExtra(
-                                Intent.EXTRA_SHORTCUT_NAME,getContext().getString(
-                                        R.string.group_applications));
-                    } else {
-                        ComponentName name = new ComponentName(info.activityInfo.packageName, 
-                                info.activityInfo.name);
-                        createShortcutIntent.setComponent(name);
-                    }
-                    mLauncher.prepareAddItemFromHomeCustomizationDrawer();
-                    mLauncher.processShortcut(createShortcutIntent);
-                }
-            });
+            ResolveInfo info = (ResolveInfo) animView.getTag();
+            createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+            createItemInfo.componentName = new ComponentName(
+                    info.activityInfo.packageName, info.activityInfo.name);
+            mDragController.startDrag(
+                    v, this, createItemInfo, DragController.DRAG_ACTION_COPY, null);
+            return true;
+        case ApplicationCustomization:
+            // Pick up the application for dropping
+            ApplicationInfo app = (ApplicationInfo) v.getTag();
+            app = new ApplicationInfo(app);
+
+            mDragController.startDrag(v, this, app, DragController.DRAG_ACTION_COPY);
             return true;
         }
         return false;
@@ -417,12 +506,13 @@
     }
 
     private void setupPage(PagedViewCellLayout layout) {
-        layout.setCellCount(sCellCountX, sCellCountY);
-        layout.setPadding(20, 10, 20, 0);
+        layout.setCellCount(mCellCountX, mCellCountY);
+        layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, mPageLayoutPaddingRight,
+                mPageLayoutPaddingBottom);
     }
 
     private void setupWorkspaceLayout() {
-        mWorkspaceWidgetLayout.setCellCount(sCellCountX, sCellCountY);
+        mWorkspaceWidgetLayout.setCellCount(mCellCountX, mCellCountY);
         mWorkspaceWidgetLayout.setPadding(20, 10, 20, 0);
 
         mMaxWidgetWidth = mWorkspaceWidgetLayout.estimateCellWidth(sMaxWidgetCellHSpan);
@@ -486,7 +576,7 @@
         removeAllViews();
 
         // ensure that we have the right number of pages
-        int numPages = (int) Math.ceil((float) list.size() / (sCellCountX * sCellCountY));
+        int numPages = (int) Math.ceil((float) list.size() / (mCellCountX * mCellCountY));
         for (int i = 0; i < numPages; ++i) {
             PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
             setupPage(layout);
@@ -496,7 +586,7 @@
 
     private void syncListPageItems(int page, List<ResolveInfo> list) {
         // ensure that we have the right number of items on the pages
-        int numCells = sCellCountX * sCellCountY;
+        int numCells = mCellCountX * mCellCountY;
         int startIndex = page * numCells;
         int endIndex = Math.min(startIndex + numCells, list.size());
         PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
@@ -514,8 +604,48 @@
             }
 
             final int index = i - startIndex;
-            final int x = index % sCellCountX;
-            final int y = index / sCellCountX;
+            final int x = index % mCellCountX;
+            final int y = index / mCellCountX;
+            setupPage(layout);
+            layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+        }
+    }
+
+    private void syncAppPages() {
+        if (mApps == null) return;
+
+        // We need to repopulate with PagedViewCellLayouts
+        removeAllViews();
+
+        // Ensure that we have the right number of pages
+        int numPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
+        for (int i = 0; i < numPages; ++i) {
+            PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
+            setupPage(layout);
+            addView(layout);
+        }
+    }
+
+    private void syncAppPageItems(int page) {
+        if (mApps == null) return;
+
+        // ensure that we have the right number of items on the pages
+        int numCells = mCellCountX * mCellCountY;
+        int startIndex = page * numCells;
+        int endIndex = Math.min(startIndex + numCells, mApps.size());
+        PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
+        // TODO: we can optimize by just re-applying to existing views
+        layout.removeAllViews();
+        for (int i = startIndex; i < endIndex; ++i) {
+            final ApplicationInfo info = mApps.get(i);
+            PagedViewIcon icon = (PagedViewIcon) mInflater.inflate(
+                    R.layout.all_apps_paged_view_application, layout, false);
+            icon.applyFromApplicationInfo(info, mPageViewIconCache);
+            icon.setOnLongClickListener(this);
+
+            final int index = i - startIndex;
+            final int x = index % mCellCountX;
+            final int y = index / mCellCountX;
             setupPage(layout);
             layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
         }
@@ -540,6 +670,10 @@
             syncListPages(mWallpaperList);
             centerPagedViewCellLayouts = true;
             break;
+        case ApplicationCustomization:
+            syncAppPages();
+            centerPagedViewCellLayouts = false;
+            break;
         default:
             removeAllViews();
             setCurrentPage(0);
@@ -579,6 +713,9 @@
         case WallpaperCustomization:
             syncListPageItems(page, mWallpaperList);
             break;
+        case ApplicationCustomization:
+            syncAppPageItems(page);
+            break;
         }
     }
 
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index aeaf5a3..1f54b36 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -190,6 +190,10 @@
         }
     }
 
+    public boolean isDropEnabled() {
+        return true;
+    }
+
     private void createAnimations() {
         if (mInAnimation == null) {
             mInAnimation = new FastAnimationSet();
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 7fc905b..87b3473 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -18,16 +18,17 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.os.IBinder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Vibrator;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.View;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.InputMethodManager;
 
@@ -568,6 +569,9 @@
         final int count = dropTargets.size();
         for (int i=count-1; i>=0; i--) {
             DropTarget target = dropTargets.get(i);
+            if (!target.isDropEnabled())
+                continue;
+
             target.getHitRect(r);
 
             // Convert the hit rect to screen coordinates
diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java
index 41e76f0..d14f5f7 100644
--- a/src/com/android/launcher2/DragView.java
+++ b/src/com/android/launcher2/DragView.java
@@ -76,8 +76,7 @@
         scale.setScale(scaleFactor, scaleFactor);
 
         mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
-        mDragRegionWidth = width;
-        mDragRegionHeight = height;
+        setDragRegion(0, 0, width, height);
 
         // The point in our scaled bitmap that the touch events are located
         mRegistrationX = registrationX + (DRAG_SCALE / 2);
@@ -91,6 +90,22 @@
         mDragRegionHeight = height;
     }
 
+    public int getScaledDragRegionXOffset() {
+        return -(int)((mScale - 1.0f) * mDragRegionWidth / 2);
+    }
+
+    public int getScaledDragRegionWidth() {
+        return (int)(mScale * mDragRegionWidth);
+    }
+
+    public int getScaledDragRegionYOffset() {
+        return -(int)((mScale - 1.0f) * mDragRegionHeight / 2);
+    }
+
+    public int getScaledDragRegionHeight() {
+        return (int)(mScale * mDragRegionWidth);
+    }
+
     public int getDragRegionLeft() {
         return mDragRegionLeft;
     }
diff --git a/src/com/android/launcher2/DropTarget.java b/src/com/android/launcher2/DropTarget.java
index d2e3ace..308dbbe 100644
--- a/src/com/android/launcher2/DropTarget.java
+++ b/src/com/android/launcher2/DropTarget.java
@@ -23,6 +23,12 @@
  *
  */
 public interface DropTarget {
+    /**
+     * Used to temporarily disable certain drop targets
+     *
+     * @return boolean specifying whether this drop target is currently enabled
+     */
+    boolean isDropEnabled();
 
     /**
      * Handle an object being dropped on the DropTarget
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index e2cef0e..e692d20 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -29,7 +29,7 @@
 /**
  * An icon that can appear on in the workspace representing an {@link UserFolder}.
  */
-public class FolderIcon extends BubbleTextView implements DropTarget {
+public class FolderIcon extends DimmableBubbleTextView implements DropTarget {
     private UserFolderInfo mInfo;
     private Launcher mLauncher;
     private Drawable mCloseIcon;
@@ -43,6 +43,10 @@
         super(context);
     }
 
+    public boolean isDropEnabled() {
+        return !((Workspace)getParent().getParent()).isSmall();
+    }
+
     static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
             UserFolderInfo folderInfo) {
 
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index 992bab1..caeb12b 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -50,11 +50,6 @@
         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
 
         if (findEmptyCell(context, mCoordinates, screen)) {
-            CellLayout.CellInfo cell = new CellLayout.CellInfo();
-            cell.cellX = mCoordinates[0];
-            cell.cellY = mCoordinates[1];
-            cell.screen = screen;
-
             Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
 
             if (intent.getAction() == null) {
@@ -66,7 +61,7 @@
             boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
             if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
                 ((LauncherApplication)context.getApplicationContext()).getModel()
-                        .addShortcut(context, data, cell, true);
+                        .addShortcut(context, data, screen, mCoordinates[0], mCoordinates[1], true);
                 Toast.makeText(context, context.getString(R.string.shortcut_installed, name),
                         Toast.LENGTH_SHORT).show();
             } else {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index d619aa2..019cd7b 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -118,8 +118,6 @@
     static final boolean DEBUG_WIDGETS = false;
     static final boolean DEBUG_USER_INTERFACE = false;
 
-    private static final int WALLPAPER_SCREENS_SPAN = 2;
-
     private static final int MENU_GROUP_ADD = 1;
     private static final int MENU_GROUP_WALLPAPER = MENU_GROUP_ADD + 1;
 
@@ -160,16 +158,6 @@
     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cellX";
     // Type: int
     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cellY";
-    // Type: int
-    private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_spanX";
-    // Type: int
-    private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_spanY";
-    // Type: int
-    private static final String RUNTIME_STATE_PENDING_ADD_COUNT_X = "launcher.add_countX";
-    // Type: int
-    private static final String RUNTIME_STATE_PENDING_ADD_COUNT_Y = "launcher.add_countY";
-    // Type: int[]
-    private static final String RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS = "launcher.add_occupied_cells";
     // Type: boolean
     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";
     // Type: long
@@ -177,6 +165,7 @@
 
     // tags for the customization tabs
     private static final String WIDGETS_TAG = "widgets";
+    private static final String APPLICATIONS_TAG = "applications";
     private static final String FOLDERS_TAG = "folders";
     private static final String SHORTCUTS_TAG = "shortcuts";
     private static final String WALLPAPERS_TAG = "wallpapers";
@@ -203,10 +192,12 @@
     private AppWidgetManager mAppWidgetManager;
     private LauncherAppWidgetHost mAppWidgetHost;
 
-    private CellLayout.CellInfo mAddItemCellInfo;
-    private int[] mAddItemCoordinates;
-    private CellLayout.CellInfo mMenuAddInfo;
-    private final int[] mCellCoordinates = new int[2];
+    private int mAddScreen = -1;
+    private int mAddIntersectCellX = -1;
+    private int mAddIntersectCellY = -1;
+    private int[] mAddDropPosition;
+    private int[] mTmpAddItemCellCoordinates = new int[2];
+
     private FolderInfo mFolderInfo;
 
     private DeleteZone mDeleteZone;
@@ -292,15 +283,18 @@
             String widgetsLabel = getString(R.string.widgets_tab_label);
             mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(WIDGETS_TAG)
                     .setIndicator(widgetsLabel).setContent(contentFactory));
+            String applicationsLabel = getString(R.string.applications_tab_label);
+            mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(APPLICATIONS_TAG)
+                    .setIndicator(applicationsLabel).setContent(contentFactory));
             String foldersLabel = getString(R.string.folders_tab_label);
             mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(FOLDERS_TAG)
                     .setIndicator(foldersLabel).setContent(contentFactory));
-            String shortcutsLabel = getString(R.string.shortcuts_tab_label);
-            mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(SHORTCUTS_TAG)
-                    .setIndicator(shortcutsLabel).setContent(contentFactory));
             String wallpapersLabel = getString(R.string.wallpapers_tab_label);
             mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(WALLPAPERS_TAG)
                     .setIndicator(wallpapersLabel).setContent(contentFactory));
+            String shortcutsLabel = getString(R.string.shortcuts_tab_label);
+            mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(SHORTCUTS_TAG)
+                    .setIndicator(shortcutsLabel).setContent(contentFactory));
 
             // TEMP: just styling the tab widget to be a bit nicer until we get the actual
             // new assets
@@ -327,20 +321,23 @@
                             if (tag == WIDGETS_TAG) {
                                 mCustomizePagedView.setCustomizationFilter(
                                     CustomizePagedView.CustomizationType.WidgetCustomization);
+                            } else if (tag == APPLICATIONS_TAG) {
+                                mCustomizePagedView.setCustomizationFilter(
+                                        CustomizePagedView.CustomizationType.ApplicationCustomization);
                             } else if (tag == FOLDERS_TAG) {
                                 mCustomizePagedView.setCustomizationFilter(
                                     CustomizePagedView.CustomizationType.FolderCustomization);
-                            } else if (tag == SHORTCUTS_TAG) {
-                                mCustomizePagedView.setCustomizationFilter(
-                                    CustomizePagedView.CustomizationType.ShortcutCustomization);
                             } else if (tag == WALLPAPERS_TAG) {
                                 mCustomizePagedView.setCustomizationFilter(
                                     CustomizePagedView.CustomizationType.WallpaperCustomization);
+                            } else if (tag == SHORTCUTS_TAG) {
+                                mCustomizePagedView.setCustomizationFilter(
+                                        CustomizePagedView.CustomizationType.ShortcutCustomization);
                             }
 
                             final float alpha = mCustomizePagedView.getAlpha();
-                            ValueAnimator alphaAnim = new ObjectAnimator(duration, mCustomizePagedView,
-                                    "alpha", alpha, 1.0f);
+                            ValueAnimator alphaAnim = new ObjectAnimator(duration,
+                                    mCustomizePagedView, "alpha", alpha, 1.0f);
                             alphaAnim.start();
                         }
                     });
@@ -655,29 +652,30 @@
         // For example, the user would PICK_SHORTCUT for "Music playlist", and we
         // launch over to the Music app to actually CREATE_SHORTCUT.
 
-        if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
+        if (resultCode == RESULT_OK && mAddScreen != -1) {
             switch (requestCode) {
                 case REQUEST_PICK_APPLICATION:
-                    completeAddApplication(this, data, mAddItemCellInfo);
+                    completeAddApplication(
+                            this, data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
                     break;
                 case REQUEST_PICK_SHORTCUT:
                     processShortcut(data);
                     break;
                 case REQUEST_CREATE_SHORTCUT:
-                    completeAddShortcut(data, mAddItemCellInfo);
+                    completeAddShortcut(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
                     break;
                 case REQUEST_PICK_LIVE_FOLDER:
                     addLiveFolder(data);
                     break;
                 case REQUEST_CREATE_LIVE_FOLDER:
-                    completeAddLiveFolder(data, mAddItemCellInfo);
+                    completeAddLiveFolder(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
                     break;
                 case REQUEST_PICK_APPWIDGET:
                     addAppWidgetFromPick(data);
                     break;
                 case REQUEST_CREATE_APPWIDGET:
                     int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-                    completeAddAppWidget(appWidgetId, mAddItemCellInfo);
+                    completeAddAppWidget(appWidgetId, mAddScreen);
                     break;
                 case REQUEST_PICK_WALLPAPER:
                     // We just wanted the activity result here so we can clear mWaitingForResult
@@ -814,20 +812,11 @@
         }
 
         final int addScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);
+
         if (addScreen > -1) {
-            mAddItemCoordinates = null;
-            mAddItemCellInfo = new CellLayout.CellInfo();
-            final CellLayout.CellInfo addItemCellInfo = mAddItemCellInfo;
-            addItemCellInfo.valid = true;
-            addItemCellInfo.screen = addScreen;
-            addItemCellInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);
-            addItemCellInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);
-            addItemCellInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);
-            addItemCellInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);
-            addItemCellInfo.updateOccupiedCells(
-                    savedState.getBooleanArray(RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS),
-                    savedState.getInt(RUNTIME_STATE_PENDING_ADD_COUNT_X),
-                    savedState.getInt(RUNTIME_STATE_PENDING_ADD_COUNT_Y));
+            mAddScreen = addScreen;
+            mAddIntersectCellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);
+            mAddIntersectCellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);
             mRestoring = true;
         }
 
@@ -1014,9 +1003,15 @@
      * @param data The intent describing the application.
      * @param cellInfo The position on screen where to create the shortcut.
      */
-    void completeAddApplication(Context context, Intent data, CellLayout.CellInfo cellInfo) {
-        cellInfo.screen = mWorkspace.getCurrentPage();
-        if (!findSingleSlot(cellInfo)) return;
+    void completeAddApplication(Context context, Intent data, int screen,
+            int intersectCellX, int intersectCellY) {
+        final int[] cellXY = mTmpAddItemCellCoordinates;
+        final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
+
+        if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
+            showOutOfSpaceMessage();
+            return;
+        }
 
         final ShortcutInfo info = mModel.getShortcutInfo(context.getPackageManager(),
                 data, context);
@@ -1025,7 +1020,8 @@
             info.setActivity(data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK |
                     Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
             info.container = ItemInfo.NO_ID;
-            mWorkspace.addApplicationShortcut(info, cellInfo, isWorkspaceLocked());
+            mWorkspace.addApplicationShortcut(info, screen, cellXY[0], cellXY[1],
+                    isWorkspaceLocked(), mAddIntersectCellX, mAddIntersectCellY);
         } else {
             Log.e(TAG, "Couldn't find ActivityInfo for selected application: " + data);
         }
@@ -1037,16 +1033,22 @@
      * @param data The intent describing the shortcut.
      * @param cellInfo The position on screen where to create the shortcut.
      */
-    private void completeAddShortcut(Intent data, CellLayout.CellInfo cellInfo) {
-        cellInfo.screen = mWorkspace.getCurrentPage();
-        if (!findSingleSlot(cellInfo)) return;
+    private void completeAddShortcut(Intent data, int screen,
+            int intersectCellX, int intersectCellY) {
+        final int[] cellXY = mTmpAddItemCellCoordinates;
+        final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
 
-        final ShortcutInfo info = mModel.addShortcut(this, data, cellInfo, false);
+        if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
+            showOutOfSpaceMessage();
+            return;
+        }
+
+        final ShortcutInfo info = mModel.addShortcut(
+                this, data, screen, cellXY[0], cellXY[1], false);
 
         if (!mRestoring) {
             final View view = createShortcut(info);
-            mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1,
-                    isWorkspaceLocked());
+            mWorkspace.addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
         }
     }
 
@@ -1057,46 +1059,58 @@
      * @param appWidgetId The app widget id
      * @param cellInfo The position on screen where to create the widget.
      */
-    private void completeAddAppWidget(int appWidgetId, CellLayout.CellInfo cellInfo) {
+    private void completeAddAppWidget(int appWidgetId, int screen) {
         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
 
         // Calculate the grid spans needed to fit this widget
-        CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
-        int[] spans = layout.rectToCell(appWidgetInfo.minWidth, appWidgetInfo.minHeight, null);
+        CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
+        int[] spanXY = layout.rectToCell(appWidgetInfo.minWidth, appWidgetInfo.minHeight, null);
 
         // Try finding open space on Launcher screen
         // We have saved the position to which the widget was dragged-- this really only matters
         // if we are placing widgets on a "spring-loaded" screen
-        final int[] xy = mCellCoordinates;
+        final int[] cellXY = mTmpAddItemCellCoordinates;
 
         // For now, we don't save the coordinate where we dropped the icon because we're not
         // supporting spring-loaded mini-screens; however, leaving the ability to directly place
         // a widget on the home screen in case we want to add it in the future
-        final int[] xyTouch = null;
-        //final int[] xyTouch = mAddItemCoordinates;
+        final int[] touchXY = null;
+        //final int[] touchXY = mAddDropPosition;
         boolean findNearestVacantAreaFailed = false;
-        if (xyTouch != null) {
-            CellLayout screen = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
-            int[] result = screen.findNearestVacantArea(
-                    mAddItemCoordinates[0], mAddItemCoordinates[1],
-                    spans[0], spans[1], cellInfo, xy);
+        boolean foundCellSpan = false;
+        if (touchXY != null) {
+            // when dragging and dropping, just find the closest free spot
+            CellLayout screenLayout = (CellLayout) mWorkspace.getChildAt(screen);
+            int[] result = screenLayout.findNearestVacantArea(
+                    touchXY[0], touchXY[1], spanXY[0], spanXY[1], cellXY);
             findNearestVacantAreaFailed = (result == null);
+            foundCellSpan = !findNearestVacantAreaFailed;
+        } else {
+            if (mAddIntersectCellX != -1 && mAddIntersectCellY != -1) {
+                // if we long pressed on an empty cell to bring up a menu,
+                // make sure we intersect the empty cell
+                foundCellSpan = layout.findCellForSpanThatIntersects(cellXY, spanXY[0], spanXY[1],
+                        mAddIntersectCellX, mAddIntersectCellY);
+            } else {
+                // if we went through the menu -> add, just find any spot
+                foundCellSpan = layout.findCellForSpan(cellXY, spanXY[0], spanXY[1]);
+            }
         }
 
-        if (findNearestVacantAreaFailed ||
-                (xyTouch == null && !findSlot(cellInfo, xy, spans[0], spans[1]))) {
+        if (!foundCellSpan) {
             if (appWidgetId != -1) mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+            showOutOfSpaceMessage();
             return;
         }
 
         // Build Launcher-specific widget info and save to database
         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId);
-        launcherInfo.spanX = spans[0];
-        launcherInfo.spanY = spans[1];
+        launcherInfo.spanX = spanXY[0];
+        launcherInfo.spanY = spanXY[1];
 
         LauncherModel.addItemToDatabase(this, launcherInfo,
                 LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                cellInfo.screen, xy[0], xy[1], false);
+                screen, cellXY[0], cellXY[1], false);
 
         if (!mRestoring) {
             mDesktopItems.add(launcherInfo);
@@ -1107,11 +1121,15 @@
             launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);
             launcherInfo.hostView.setTag(launcherInfo);
 
-            mWorkspace.addInScreen(launcherInfo.hostView, cellInfo.screen, xy[0], xy[1],
+            mWorkspace.addInScreen(launcherInfo.hostView, screen, cellXY[0], cellXY[1],
                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
         }
     }
 
+    void showOutOfSpaceMessage() {
+        Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+    }
+
     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {
         mDesktopItems.remove(launcherInfo);
         launcherInfo.hostView = null;
@@ -1212,19 +1230,10 @@
             outState.putBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, true);
         }
 
-        if (mAddItemCellInfo != null && mAddItemCellInfo.valid && mWaitingForResult) {
-            final CellLayout.CellInfo addItemCellInfo = mAddItemCellInfo;
-            final CellLayout layout = (CellLayout) mWorkspace.getChildAt(addItemCellInfo.screen);
-
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, addItemCellInfo.screen);
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, addItemCellInfo.cellX);
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, addItemCellInfo.cellY);
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, addItemCellInfo.spanX);
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, addItemCellInfo.spanY);
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_COUNT_X, layout.getCountX());
-            outState.putInt(RUNTIME_STATE_PENDING_ADD_COUNT_Y, layout.getCountY());
-            outState.putBooleanArray(RUNTIME_STATE_PENDING_ADD_OCCUPIED_CELLS,
-                   layout.getOccupiedCellsFlattened());
+        if (mAddScreen > -1 && mWaitingForResult) {
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, mAddScreen);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mAddIntersectCellX);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mAddIntersectCellY);
         }
 
         if (mFolderInfo != null && mWaitingForResult) {
@@ -1346,20 +1355,13 @@
 
         // Disable add if the workspace is full.
         if (visible) {
-            mMenuAddInfo = mWorkspace.updateOccupiedCellsForCurrentScreen(null);
-            menu.setGroupEnabled(MENU_GROUP_ADD, mMenuAddInfo != null && mMenuAddInfo.valid);
+            CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
+            menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell());
         }
 
         return true;
     }
 
-    // we need to initialize mAddItemCellInfo before adding something to the homescreen -- when
-    // using the settings menu to add an item, something similar happens in showAddDialog
-    public void prepareAddItemFromHomeCustomizationDrawer() {
-        mMenuAddInfo = mWorkspace.updateOccupiedCellsForCurrentScreen(null);
-        mAddItemCellInfo = mMenuAddInfo;
-    }
-
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -1403,16 +1405,24 @@
             }
         } else {
             closeAllApps(true);
-            showAddDialog(mMenuAddInfo);
+            showAddDialog(-1, -1);
         }
     }
 
-    void addAppWidgetFromDrop(ComponentName appWidgetProvider, CellLayout.CellInfo cellInfo,
-            int[] position) {
-        mAddItemCellInfo = cellInfo;
+    private void resetAddInfo() {
+        mAddScreen = -1;
+        mAddIntersectCellX = -1;
+        mAddIntersectCellY = -1;
+        mAddDropPosition = null;
+    }
 
-        // only set mAddItemCoordinates if we dropped on home screen in "spring-loaded" manner
-        mAddItemCoordinates = position;
+    void addAppWidgetFromDrop(ComponentName appWidgetProvider, int screen, int[] position) {
+        resetAddInfo();
+        mAddScreen = screen;
+
+        // only set mAddDropPosition if we dropped on home screen in "spring-loaded" manner
+        mAddDropPosition = position;
+
         int appWidgetId = getAppWidgetHost().allocateAppWidgetId();
         AppWidgetManager.getInstance(this).bindAppWidgetId(appWidgetId, appWidgetProvider);
         addAppWidgetImpl(appWidgetId);
@@ -1438,10 +1448,20 @@
             startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
         } else {
             // Otherwise just add it
-            completeAddAppWidget(appWidgetId, mAddItemCellInfo);
+            completeAddAppWidget(appWidgetId, mAddScreen);
         }
     }
 
+    void processShortcutFromDrop(ComponentName componentName, int screen, int[] position) {
+        resetAddInfo();
+        mAddScreen = screen;
+        mAddDropPosition = position;
+
+        Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+        createShortcutIntent.setComponent(componentName);
+        processShortcut(createShortcutIntent);
+    }
+
     void processShortcut(Intent intent) {
         // Handle case where user selected "Applications"
         String applicationName = getResources().getString(R.string.group_applications);
@@ -1463,59 +1483,76 @@
         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);
     }
 
-    void addLiveFolder(Intent intent) {
+    void addLiveFolderFromDrop(ComponentName componentName, int screen, int[] position) {
+        resetAddInfo();
+        mAddScreen = screen;
+        mAddDropPosition = position;
+
+        Intent createFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
+        createFolderIntent.setComponent(componentName);
+
+        addLiveFolder(createFolderIntent);
+    }
+
+    void addLiveFolder(Intent intent) { // YYY add screen intersect etc. parameters here
         // 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();
+            addFolder(mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
         } else {
             startActivityForResult(intent, REQUEST_CREATE_LIVE_FOLDER);
         }
     }
 
-    void addFolder() {
+    void addFolder(int screen, int intersectCellX, int intersectCellY) {
         UserFolderInfo folderInfo = new UserFolderInfo();
         folderInfo.title = getText(R.string.folder_name);
 
-        CellLayout.CellInfo cellInfo = mAddItemCellInfo;
-        cellInfo.screen = mWorkspace.getCurrentPage();
-        if (!findSingleSlot(cellInfo)) return;
+        final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
+        final int[] cellXY = mTmpAddItemCellCoordinates;
+        if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
+            showOutOfSpaceMessage();
+            return;
+        }
 
         // Update the model
         LauncherModel.addItemToDatabase(this, folderInfo,
                 LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                mWorkspace.getCurrentPage(), cellInfo.cellX, cellInfo.cellY, false);
+                screen, cellXY[0], cellXY[1], false);
         sFolders.put(folderInfo.id, folderInfo);
 
         // Create the view
         FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), folderInfo);
-        mWorkspace.addInCurrentScreen(newFolder,
-                cellInfo.cellX, cellInfo.cellY, 1, 1, isWorkspaceLocked());
+        mWorkspace.addInScreen(newFolder, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
     }
 
     void removeFolder(FolderInfo folder) {
         sFolders.remove(folder.id);
     }
 
-    private void completeAddLiveFolder(Intent data, CellLayout.CellInfo cellInfo) {
-        cellInfo.screen = mWorkspace.getCurrentPage();
-        if (!findSingleSlot(cellInfo)) return;
+    private void completeAddLiveFolder(
+            Intent data, int screen, int intersectCellX, int intersectCellY) {
+        final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
+        final int[] cellXY = mTmpAddItemCellCoordinates;
+        if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
+            showOutOfSpaceMessage();
+            return;
+        }
 
-        final LiveFolderInfo info = addLiveFolder(this, data, cellInfo, false);
+        final LiveFolderInfo info = addLiveFolder(this, data, screen, cellXY[0], cellXY[1], false);
 
         if (!mRestoring) {
             final View view = LiveFolderIcon.fromXml(R.layout.live_folder_icon, this,
                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
-            mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1,
-                    isWorkspaceLocked());
+            mWorkspace.addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
         }
     }
 
     static LiveFolderInfo addLiveFolder(Context context, Intent data,
-            CellLayout.CellInfo cellInfo, boolean notify) {
+            int screen, int cellX, int cellY, boolean notify) {
 
         Intent baseIntent = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT);
         String name = data.getStringExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME);
@@ -1551,34 +1588,12 @@
                 LiveFolders.DISPLAY_MODE_GRID);
 
         LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
+                screen, cellX, cellY, notify);
         sFolders.put(info.id, info);
 
         return info;
     }
 
-    private boolean findSingleSlot(CellLayout.CellInfo cellInfo) {
-        final int[] xy = new int[2];
-        if (findSlot(cellInfo, xy, 1, 1)) {
-            cellInfo.cellX = xy[0];
-            cellInfo.cellY = xy[1];
-            return true;
-        }
-        return false;
-    }
-
-    private boolean findSlot(CellLayout.CellInfo cellInfo, int[] xy, int spanX, int spanY) {
-        if (!cellInfo.findCellForSpan(xy, spanX, spanY)) {
-            CellLayout targetLayout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
-            cellInfo = targetLayout.updateOccupiedCells(null, null);
-            if (!cellInfo.findCellForSpan(xy, spanX, spanY)) {
-                Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
-                return false;
-            }
-        }
-        return true;
-    }
-
     private void showNotifications() {
         final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);
         if (statusBar != null) {
@@ -1900,28 +1915,38 @@
             v = (View) v.getParent();
         }
 
-        CellLayout.CellInfo cellInfo = (CellLayout.CellInfo) v.getTag();
 
+        resetAddInfo();
+        CellLayout.CellInfo longClickCellInfo = (CellLayout.CellInfo) v.getTag();
         // This happens when long clicking an item with the dpad/trackball
-        if (cellInfo == null) {
+        if (longClickCellInfo == null || !longClickCellInfo.valid) {
             return true;
         }
 
+        final View itemUnderLongClick = longClickCellInfo.cell;
+
         if (mWorkspace.allowLongPress()) {
-            if (cellInfo.cell == null) {
-                if (cellInfo.valid) {
-                    // User long pressed on empty space
-                    mWorkspace.setAllowLongPress(false);
-                    mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
-                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-                    showAddDialog(cellInfo);
+            if (itemUnderLongClick == null) {
+                // User long pressed on empty space
+                mWorkspace.setAllowLongPress(false);
+                mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
+                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+                if (LauncherApplication.isScreenXLarge()) {
+                    // Animate the widget chooser up from the bottom of the screen
+                    if (!isCustomizationDrawerVisible()) {
+                        showCustomizationDrawer(true);
+                    }
+                } else {
+                    showAddDialog(longClickCellInfo.cellX, longClickCellInfo.cellY);
                 }
             } else {
-                if (!(cellInfo.cell instanceof Folder)) {
+                if (!(itemUnderLongClick instanceof Folder)) {
                     // User long pressed on an item
                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-                    mWorkspace.startDrag(cellInfo);
+                    mAddIntersectCellX = longClickCellInfo.cellX;
+                    mAddIntersectCellY = longClickCellInfo.cellY;
+                    mWorkspace.startDrag(longClickCellInfo);
                 }
             }
         }
@@ -2099,9 +2124,11 @@
         showDialog(DIALOG_RENAME_FOLDER);
     }
 
-    private void showAddDialog(CellLayout.CellInfo cellInfo) {
-        mAddItemCellInfo = cellInfo;
-        mAddItemCoordinates = null;
+    private void showAddDialog(int intersectX, int intersectY) {
+        resetAddInfo();
+        mAddIntersectCellX = intersectX;
+        mAddIntersectCellY = intersectY;
+        mAddScreen = mWorkspace.getCurrentPage();
         mWaitingForResult = true;
         showDialog(DIALOG_CREATE_SHORTCUT);
     }
@@ -2627,7 +2654,7 @@
                 mAllAppsPagedView.endChoiceMode();
                 mCustomizePagedView.endChoiceMode();
             } else {
-                Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+                showOutOfSpaceMessage();
             }
         }
     }
@@ -2976,6 +3003,7 @@
      */
     public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
         mAllAppsGrid.setApps(apps);
+        mCustomizePagedView.setApps(apps);
         updateAppMarketIcon();
     }
 
@@ -2987,6 +3015,7 @@
     public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
         removeDialog(DIALOG_CREATE_SHORTCUT);
         mAllAppsGrid.addApps(apps);
+        mCustomizePagedView.addApps(apps);
         updateAppMarketIcon();
     }
 
@@ -2999,6 +3028,7 @@
         removeDialog(DIALOG_CREATE_SHORTCUT);
         mWorkspace.updateShortcuts(apps);
         mAllAppsGrid.updateApps(apps);
+        mCustomizePagedView.updateApps(apps);
         updateAppMarketIcon();
     }
 
@@ -3013,6 +3043,7 @@
             mWorkspace.removeItems(apps);
         }
         mAllAppsGrid.removeApps(apps);
+        mCustomizePagedView.removeApps(apps);
         updateAppMarketIcon();
     }
 
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 4ad31b1..7c1fa21 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1478,11 +1478,11 @@
     }
 
     ShortcutInfo addShortcut(Context context, Intent data,
-            CellLayout.CellInfo cellInfo, boolean notify) {
+            int screen, int cellX, int cellY, boolean notify) {
 
         final ShortcutInfo info = infoFromShortcutIntent(context, data);
         addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
+                screen, cellX, cellY, notify);
 
         return info;
     }
diff --git a/src/com/android/launcher2/PendingAddItemInfo.java b/src/com/android/launcher2/PendingAddItemInfo.java
new file mode 100644
index 0000000..23e2330
--- /dev/null
+++ b/src/com/android/launcher2/PendingAddItemInfo.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher2;
+
+import android.content.ComponentName;
+
+/**
+ * We pass this object with a drag from the customization tray
+ */
+class PendingAddItemInfo extends ItemInfo {
+    /**
+     * The component that will be created.
+     */
+    ComponentName componentName;
+}
\ No newline at end of file
diff --git a/src/com/android/launcher2/UserFolder.java b/src/com/android/launcher2/UserFolder.java
index c7466b8..d6799f7 100644
--- a/src/com/android/launcher2/UserFolder.java
+++ b/src/com/android/launcher2/UserFolder.java
@@ -72,6 +72,10 @@
         }
     }
 
+    public boolean isDropEnabled() {
+        return true;
+    }
+
     void bind(FolderInfo info) {
         super.bind(info);
         setContentAdapter(new ShortcutsAdapter(mContext, ((UserFolderInfo) info).contents));
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 599fbda..1934cd5 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,12 +16,12 @@
 
 package com.android.launcher2;
 
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
 import com.android.launcher.R;
 
-import android.animation.PropertyValuesHolder;
+import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.animation.Animator.AnimatorListener;
 import android.app.WallpaperManager;
 import android.appwidget.AppWidgetManager;
@@ -46,7 +46,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -103,8 +102,10 @@
 
     private int[] mTempCell = new int[2];
     private int[] mTempEstimate = new int[2];
+    private float[] mTempOriginXY = new float[2];
     private float[] mTempDragCoordinates = new float[2];
     private float[] mTempDragBottomRightCoordinates = new float[2];
+    private Matrix mTempInverseMatrix = new Matrix();
 
     private static final int DEFAULT_CELL_COUNT_X = 4;
     private static final int DEFAULT_CELL_COUNT_Y = 4;
@@ -117,7 +118,6 @@
     private boolean mIsSmall;
     private AnimatorListener mUnshrinkAnimationListener;
 
-
     /**
      * Used to inflate the Workspace from XML.
      *
@@ -274,35 +274,6 @@
     }
 
     /**
-     * Adds the specified child in the current screen. The position and dimension of
-     * the child are defined by x, y, spanX and spanY.
-     *
-     * @param child The child to add in one of the workspace's screens.
-     * @param x The X position of the child in the screen's grid.
-     * @param y The Y position of the child in the screen's grid.
-     * @param spanX The number of cells spanned horizontally by the child.
-     * @param spanY The number of cells spanned vertically by the child.
-     */
-    void addInCurrentScreen(View child, int x, int y, int spanX, int spanY) {
-        addInScreen(child, mCurrentPage, x, y, spanX, spanY, false);
-    }
-
-    /**
-     * Adds the specified child in the current screen. The position and dimension of
-     * the child are defined by x, y, spanX and spanY.
-     *
-     * @param child The child to add in one of the workspace's screens.
-     * @param x The X position of the child in the screen's grid.
-     * @param y The Y position of the child in the screen's grid.
-     * @param spanX The number of cells spanned horizontally by the child.
-     * @param spanY The number of cells spanned vertically by the child.
-     * @param insert When true, the child is inserted at the beginning of the children list.
-     */
-    void addInCurrentScreen(View child, int x, int y, int spanX, int spanY, boolean insert) {
-        addInScreen(child, mCurrentPage, x, y, spanX, spanY, insert);
-    }
-
-    /**
      * Adds the specified child in the specified screen. The position and dimension of
      * the child are defined by x, y, spanX and spanY.
      *
@@ -369,14 +340,6 @@
         }
     }
 
-    CellLayout.CellInfo updateOccupiedCellsForCurrentScreen(boolean[] occupied) {
-        CellLayout group = (CellLayout) getChildAt(mCurrentPage);
-        if (group != null) {
-            return group.updateOccupiedCells(occupied, null);
-        }
-        return null;
-    }
-
     public boolean onTouch(View v, MotionEvent event) {
         // this is an intercepted event being forwarded from a cell layout
         if (mIsSmall) {
@@ -776,43 +739,40 @@
         invalidate();
     }
 
-    void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo) {
-        addApplicationShortcut(info, cellInfo, false);
+    void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY,
+            boolean insertAtFirst, int intersectX, int intersectY) {
+        final CellLayout cellLayout = (CellLayout) getChildAt(screen);
+        View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info);
+
+        final int[] cellXY = new int[2];
+        cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY);
+        addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst);
+        LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
+                LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
+                cellXY[0], cellXY[1]);
     }
 
-    void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo,
-            boolean insertAtFirst) {
-        final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen);
-        final int[] result = new int[2];
-
-        layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result);
-        onDropExternal(result[0], result[1], info, layout, insertAtFirst);
-    }
 
     public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
-        CellLayout cellLayout = getCurrentDropLayout();
+        CellLayout cellLayout;
         int originX = x - xOffset;
         int originY = y - yOffset;
         if (mIsSmall) {
-            // find out which target layout is over
-            final float[] localXY = mTempDragCoordinates;
-            localXY[0] = originX;
-            localXY[1] = originY;
-            final float[] localBottomRightXY = mTempDragBottomRightCoordinates;
-            // we need to subtract left/top here because DragController already adds
-            // dragRegionLeft/Top to xOffset and yOffset
-            localBottomRightXY[0] = originX + dragView.getDragRegionWidth();
-            localBottomRightXY[1] = originY + dragView.getDragRegionHeight();
-            cellLayout =  findMatchingPageForDragOver(localXY, localBottomRightXY);
+            cellLayout = findMatchingPageForDragOver(dragView, originX, originY);
             if (cellLayout == null) {
                 // cancel the drag if we're not over a mini-screen at time of drop
                 // TODO: maybe add a nice fade here?
                 return;
             }
-            // localXY will be transformed into the local screen's coordinate space; save that info
-            originX = (int)localXY[0];
-            originY = (int)localXY[1];
+            // get originX and originY in the local coordinate system of the screen
+            mTempOriginXY[0] = originX;
+            mTempOriginXY[1] = originY;
+            mapPointGlobalToLocal(cellLayout, mTempOriginXY);
+            originX = (int)mTempOriginXY[0];
+            originY = (int)mTempOriginXY[1];
+        } else {
+            cellLayout = getCurrentDropLayout();
         }
         if (source != this) {
             onDropExternal(originX, originY, dragInfo, cellLayout);
@@ -835,8 +795,8 @@
 
                 // update the item's position after drop
                 final ItemInfo info = (ItemInfo) cell.getTag();
-                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell
-                        .getLayoutParams();
+                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
+                cellLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
                 lp.cellX = mTargetCell[0];
                 lp.cellY = mTargetCell[1];
 
@@ -854,6 +814,10 @@
     public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
 
+        if (mIsSmall) {
+            // If we're shrunken, don't let anyone drag on folders/etc  that are on the mini-screens
+            return null;
+        }
         // We may need to delegate the drag to a child view. If a 1x1 item
         // would land in a cell occupied by a DragTarget (e.g. a Folder),
         // then drag events should be handled by that child.
@@ -871,12 +835,12 @@
             dragPointX = x;
             dragPointY = y;
         }
+        dragPointX += mScrollX - currentLayout.getLeft();
+        dragPointY += mScrollY - currentLayout.getTop();
 
         // If we are dragging over a cell that contains a DropTarget that will
         // accept the drop, delegate to that DropTarget.
         final int[] cellXY = mTempCell;
-        int localDragPointX = dragPointX - (currentLayout.getLeft() - mScrollX);
-        int localDragPointY = dragPointY - (currentLayout.getTop() - mScrollY);
         currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY);
         View child = currentLayout.getChildAt(cellXY[0], cellXY[1]);
         if (child instanceof DropTarget) {
@@ -888,29 +852,32 @@
         return null;
     }
 
+
+    private void mapPointGlobalToLocal(View v, float[] xy) {
+        xy[0] = xy[0] + mScrollX - v.getLeft();
+        xy[1] = xy[1] + mScrollY - v.getTop();
+        v.getMatrix().invert(mTempInverseMatrix);
+        mTempInverseMatrix.mapPoints(xy);
+    }
+
     // xy = upper left corner of item being dragged
     // bottomRightXy = lower right corner of item being dragged
     // This method will see which mini-screen is most overlapped by the item being dragged, and
     // return it. It will also transform the parameters xy and bottomRightXy into the local
     // coordinate space of the returned screen
-    private CellLayout findMatchingPageForDragOver(float[] xy, float[] bottomRightXy) {
-        float x = xy[0];
-        float y = xy[1];
-        float right = bottomRightXy[0];
-        float bottom = bottomRightXy[1];
-
-        float bestX = 0;
-        float bestY = 0;
-        float bestRight = 0;
-        float bestBottom = 0;
-
-        Matrix inverseMatrix = new Matrix();
+    private CellLayout findMatchingPageForDragOver(DragView dragView, int originX, int originY) {
+        float x = originX + dragView.getScaledDragRegionXOffset();
+        float y = originY + dragView.getScaledDragRegionYOffset();
+        float right = x + dragView.getScaledDragRegionWidth();
+        float bottom = y + dragView.getScaledDragRegionHeight();
 
         // We loop through all the screens (ie CellLayouts) and see which one overlaps the most
         // with the item being dragged.
         final int screenCount = getChildCount();
         CellLayout bestMatchingScreen = null;
-        float bestOverlapSoFar = 0;
+        float smallestDistSoFar = Float.MAX_VALUE;
+        final float[] xy = mTempDragCoordinates;
+        final float[] bottomRightXy = mTempDragBottomRightCoordinates;
         for (int i = 0; i < screenCount; i++) {
             CellLayout cl = (CellLayout)getChildAt(i);
             // Transform the coordinates of the item being dragged to the CellLayout's coordinates
@@ -918,57 +885,76 @@
             float top = cl.getTop();
             xy[0] = x + mScrollX - left;
             xy[1] = y + mScrollY - top;
-            cl.getMatrix().invert(inverseMatrix);
 
             bottomRightXy[0] = right + mScrollX - left;
             bottomRightXy[1] = bottom + mScrollY - top;
 
-            inverseMatrix.mapPoints(xy);
-            inverseMatrix.mapPoints(bottomRightXy);
+            cl.getMatrix().invert(mTempInverseMatrix);
+            mTempInverseMatrix.mapPoints(xy);
+            mTempInverseMatrix.mapPoints(bottomRightXy);
 
             float dragRegionX = xy[0];
             float dragRegionY = xy[1];
             float dragRegionRight = bottomRightXy[0];
             float dragRegionBottom = bottomRightXy[1];
+            float dragRegionCenterX = (dragRegionX + dragRegionRight) / 2.0f;
+            float dragRegionCenterY = (dragRegionY + dragRegionBottom) / 2.0f;
 
             // Find the overlapping region
             float overlapLeft = Math.max(0f, dragRegionX);
             float overlapTop = Math.max(0f, dragRegionY);
             float overlapBottom = Math.min(cl.getHeight(), dragRegionBottom);
             float overlapRight = Math.min(cl.getWidth(), dragRegionRight);
-
             if (overlapRight >= 0 && overlapLeft <= cl.getWidth() &&
-                    overlapTop >= 0 && overlapBottom <= cl.getHeight()) {
-                // Calculate the size of the overlapping region
+                    (overlapTop >= 0 && overlapBottom <= cl.getHeight())) {
+                // Calculate the distance between the two centers
+                float distX = dragRegionCenterX - cl.getWidth()/2;
+                float distY = dragRegionCenterY - cl.getHeight()/2;
+                float dist = distX * distX + distY * distY;
+
                 float overlap = (overlapRight - overlapLeft) * (overlapBottom - overlapTop);
-                if (overlap > bestOverlapSoFar) {
-                    bestOverlapSoFar = overlap;
+
+                // Calculate the closest overlapping region
+                if (overlap > 0 && dist < smallestDistSoFar) {
+                    smallestDistSoFar = dist;
                     bestMatchingScreen = cl;
-                    bestX = xy[0];
-                    bestY = xy[1];
-                    bestRight = bottomRightXy[0];
-                    bestBottom = bottomRightXy[1];
                 }
              }
         }
-        if (bestMatchingScreen != null && bestMatchingScreen != mDragTargetLayout) {
+
+        if (bestMatchingScreen != mDragTargetLayout) {
             if (mDragTargetLayout != null) {
-                mDragTargetLayout.onDragComplete();
+                mDragTargetLayout.onDragExit();
             }
             mDragTargetLayout = bestMatchingScreen;
         }
-        xy[0] = bestX;
-        xy[1] = bestY;
-        bottomRightXy[0] = bestRight;
-        bottomRightXy[1] = bestBottom;
         return bestMatchingScreen;
     }
 
     public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
+        CellLayout currentLayout;
+        int originX = x - xOffset;
+        int originY = y - yOffset;
+        if (mIsSmall) {
+            currentLayout = findMatchingPageForDragOver(dragView, originX, originY);
+
+            if (currentLayout == null) {
+                return;
+            }
+
+            currentLayout.setHover(true);
+            // get originX and originY in the local coordinate system of the screen
+            mTempOriginXY[0] = originX;
+            mTempOriginXY[1] = originY;
+            mapPointGlobalToLocal(currentLayout, mTempOriginXY);
+            originX = (int)mTempOriginXY[0];
+            originY = (int)mTempOriginXY[1];
+        } else {
+            currentLayout = getCurrentDropLayout();
+        }
 
         final ItemInfo item = (ItemInfo)dragInfo;
-        CellLayout currentLayout = getCurrentDropLayout();
 
         if (dragInfo instanceof LauncherAppWidgetInfo) {
             LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo;
@@ -980,25 +966,6 @@
                 item.spanY = spans[1];
             }
         }
-        int originX = x - xOffset;
-        int originY = y - yOffset;
-        if (mIsSmall) {
-            // find out which mini screen the dragged item is over
-            final float[] localXY = mTempDragCoordinates;
-            localXY[0] = originX;
-            localXY[1] = originY;
-            final float[] localBottomRightXY = mTempDragBottomRightCoordinates;
-
-            localBottomRightXY[0] = originX + dragView.getDragRegionWidth();
-            localBottomRightXY[1] = originY + dragView.getDragRegionHeight();
-            currentLayout = findMatchingPageForDragOver(localXY, localBottomRightXY);
-            if (currentLayout != null) {
-                currentLayout.setHover(true);
-            }
-
-            originX = (int)localXY[0];
-            originY = (int)localXY[1];
-        }
 
         if (source != this) {
             // This is a hack to fix the point used to determine which cell an icon from the all
@@ -1015,7 +982,7 @@
         }
         if (currentLayout != mDragTargetLayout) {
             if (mDragTargetLayout != null) {
-                mDragTargetLayout.onDragComplete();
+                mDragTargetLayout.onDragExit();
             }
             mDragTargetLayout = currentLayout;
         }
@@ -1028,14 +995,14 @@
             int localOriginX = originX - (mDragTargetLayout.getLeft() - mScrollX);
             int localOriginY = originY - (mDragTargetLayout.getTop() - mScrollY);
             mDragTargetLayout.visualizeDropLocation(
-                    child, localOriginX, localOriginY, item.spanX, item.spanY);
+                    child, localOriginX, localOriginY, item.spanX, item.spanY, child);
         }
     }
 
     public void onDragExit(DragSource source, int x, int y, int xOffset,
             int yOffset, DragView dragView, Object dragInfo) {
         if (mDragTargetLayout != null) {
-            mDragTargetLayout.onDragComplete();
+            mDragTargetLayout.onDragExit();
             mDragTargetLayout = null;
         }
     }
@@ -1055,17 +1022,43 @@
         CellLayout cl = (CellLayout) layout;
         ItemInfo info = (ItemInfo) dragInfo;
 
-        final CellLayout.CellInfo cellInfo = cl.updateOccupiedCells(null, null);
-        if (cellInfo.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) {
+        if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) {
             onDropExternal(0, 0, dragInfo, cl, false);
             return true;
         }
+        mLauncher.showOutOfSpaceMessage();
         return false;
     }
 
+    // Drag from somewhere else
     private void onDropExternal(int x, int y, Object dragInfo,
             CellLayout cellLayout, boolean insertAtFirst) {
-        // Drag from somewhere else
+        int screen = indexOfChild(cellLayout);
+        if (dragInfo instanceof PendingAddItemInfo) {
+            PendingAddItemInfo info = (PendingAddItemInfo) dragInfo;
+            // When dragging and dropping from customization tray, we deal with creating
+            // widgets/shortcuts/folders in a slightly different way
+            int[] touchXY = new int[2];
+            touchXY[0] = x;
+            touchXY[1] = y;
+            switch (info.itemType) {
+                case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+                    mLauncher.addAppWidgetFromDrop(info.componentName, screen, touchXY);
+                    break;
+                case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
+                    mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY);
+                    break;
+                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                    mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY);
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown item type: " + info.itemType);
+            }
+            cellLayout.onDragExit();
+            return;
+        }
+
+        // This is for other drag/drop cases, like dragging from All Apps
         ItemInfo info = (ItemInfo) dragInfo;
 
         View view = null;
@@ -1082,25 +1075,15 @@
             break;
         case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
             view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
-                    (ViewGroup) getChildAt(mCurrentPage),
-                    ((UserFolderInfo) info));
-            break;
-        case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
-            cellLayout.setTagToCellInfoForPoint(x, y);
-            int[] position = new int[2];
-            position[0] = x;
-            position[1] = y;
-            mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName,
-                    cellLayout.getTag(), position);
+                    cellLayout, ((UserFolderInfo) info));
             break;
         default:
-            throw new IllegalStateException("Unknown item type: "
-                    + info.itemType);
+            throw new IllegalStateException("Unknown item type: " + info.itemType);
         }
 
         // If the view is null, it has already been added.
         if (view == null) {
-            cellLayout.onDragComplete();
+            cellLayout.onDragExit();
         } else {
             mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell);
             addInScreen(view, indexOfChild(cellLayout), mTargetCell[0],
@@ -1109,7 +1092,7 @@
             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
 
             LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
-                    LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentPage,
+                    LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
                     lp.cellX, lp.cellY);
         }
     }
@@ -1124,22 +1107,40 @@
     }
 
     /**
+     * Return the current CellInfo describing our current drag; this method exists
+     * so that Launcher can sync this object with the correct info when the activity is created/
+     * destroyed
+     *
+     */
+    public CellLayout.CellInfo getDragInfo() {
+        return mDragInfo;
+    }
+
+    /**
      * {@inheritDoc}
      */
     public boolean acceptDrop(DragSource source, int x, int y,
             int xOffset, int yOffset, DragView dragView, Object dragInfo) {
-        final CellLayout layout = getCurrentDropLayout();
+        CellLayout layout;
+        if (mIsSmall) {
+            layout = findMatchingPageForDragOver(dragView, x - xOffset, y - yOffset);
+            if (layout == null) {
+                // cancel the drag if we're not over a mini-screen at time of drop
+                return false;
+            }
+        } else {
+            layout = getCurrentDropLayout();
+        }
         final CellLayout.CellInfo dragCellInfo = mDragInfo;
         final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX;
         final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY;
 
         final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell;
-        final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView);
 
-        if (cellInfo.findCellForSpan(mTempEstimate, spanX, spanY)) {
+        if (layout.findCellForSpanIgnoring(null, spanX, spanY, ignoreView)) {
             return true;
         } else {
-            Toast.makeText(getContext(), getContext().getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+            mLauncher.showOutOfSpaceMessage();
             return false;
         }
     }
@@ -1156,9 +1157,9 @@
         layout.estimateDropCell(localPixelX, localPixelY, spanX, spanY, cellXY);
         layout.cellToPoint(cellXY[0], cellXY[1], mTempEstimate);
 
-        final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView);
         // Find the best target drop location
-        return layout.findNearestVacantArea(mTempEstimate[0], mTempEstimate[1], spanX, spanY, cellInfo, recycle);
+        return layout.findNearestVacantArea(
+                mTempEstimate[0], mTempEstimate[1], spanX, spanY, recycle);
     }
 
     /**
@@ -1196,6 +1197,10 @@
         mDragInfo = null;
     }
 
+    public boolean isDropEnabled() {
+        return true;
+    }
+
     @Override
     protected void onRestoreInstanceState(Parcelable state) {
         super.onRestoreInstanceState(state);
@@ -1366,8 +1371,6 @@
     }
 
     void updateShortcuts(ArrayList<ApplicationInfo> apps) {
-        final PackageManager pm = mLauncher.getPackageManager();
-
         final int screenCount = getChildCount();
         for (int i = 0; i < screenCount; i++) {
             final CellLayout layout = (CellLayout) getChildAt(i);