Merge "Cancelling scroll indicator animation during All Apps transition"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 60888d3..13d0acf 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Kortpaaie"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Legstukke"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Muurpapier"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Geen meer spasie op tuisskerm nie."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Geen spasie op tuisskerm oor nie."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Nie meer plek op die warmlaai nie."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Hierdie legstuk is te groot vir die hoofposisie."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Kortpad \"<xliff:g id="NAME">%s</xliff:g>\" is geskep."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Kortpad \"<xliff:g id="NAME">%s</xliff:g>\" is verwyder."</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index cf9e511..9e25766 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"አቋራጮች"</string>
     <string name="group_widgets" msgid="6704978494073105844">"ፍርግሞች"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"ልጣፍ"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"በዚህ መነሻ ማያ ላይ ምንም ቦታ የለም።"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"የመነሻ ማያ ገጾችህ ላይ ተጨማሪ ቦታ የለም።"</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"በመትከያ ቦታው ላይ ተጨማሪ ክፍል የለም።"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"ይህ ፍርግም ለማስቀመጫው በጣም ትልቅ ነው።"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"አቋራጭ\"<xliff:g id="NAME">%s</xliff:g> \"ተፈጥሯል።"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"አቋራጭ \"<xliff:g id="NAME">%s</xliff:g>\" ተወግዶ ነበር።"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 16ba2bf..3dcd631 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"الاختصارات"</string>
     <string name="group_widgets" msgid="6704978494073105844">"الأدوات"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"الخلفيات"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"ليس هناك مساحة أخرى في الشاشات الرئيسية."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"ليست هناك مساحة أخرى في منطقة الإرساء القابلة للتخصيص."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"حجم هذه الأداة كبير للغاية بحيث لا يتسع له الموقع المهم."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"تم إنشاء الاختصار \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"تمت إزالة الاختصار \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 60ecc26..459b87b 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Хуткі доступ"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Віджэты"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Шпалеры"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"На Галоўнай старонцы больш няма месца."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"На галоўных экранах больш няма месца."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"На Hotseat больш няма месца."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Гэты віджэт занадта вялікі для hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Створаны цэтлік \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Цэтлік \"<xliff:g id="NAME">%s</xliff:g>\" быў выдалены."</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index ffb5597..109e460 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Преки пътища"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Приспособления"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Тапети"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"На този начален екран няма повече място."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"На началните ви екрани няма повече място."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"В трамплина няма повече място."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Това приспособление е твърде голямо за трамплина."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Прекият път за „<xliff:g id="NAME">%s</xliff:g>“ бе създаден."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Прекият път към „<xliff:g id="NAME">%s</xliff:g>“ бе премахнат."</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index b525dcf..a520bea 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Dreceres"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Empaperats"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Ja no queda espai en aquesta pantalla Inici."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"No queda espai a les pantalles d\'inici."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"No queda espai al hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Aquest widget és massa gran per al hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"S\'ha creat la drecera \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"S\'ha eliminat la drecera \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index f2d972a..be575d4 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Zástupce"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgety"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Tapety"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Na této ploše již není místo."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Na plochách již není místo."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"V části hotseat již není místo."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Widget je pro hotseat příliš velký."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Zástupce <xliff:g id="NAME">%s</xliff:g> byl vytvořen."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Zástupce <xliff:g id="NAME">%s</xliff:g> byl odebrán."</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 43e0be0..513517d 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Genveje"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Tapeter"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Der er ikke mere plads på Startskærmen."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Der er ikke mere plads på dine startskærme."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Der er ikke mere plads på hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Denne widget er for stor til hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Genvejen \"<xliff:g id="NAME">%s</xliff:g>\" blev oprettet."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Genvejen \"<xliff:g id="NAME">%s</xliff:g>\" blev fjernet."</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1481540..91d025a 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Verknüpfungen"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Hintergründe"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Auf dem Startbildschirm ist kein Platz mehr vorhanden."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Auf Ihrem Startbildschirm ist kein Platz mehr vorhanden."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Auf der App-Leiste ist kein Platz mehr vorhanden."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Dieses Widget ist zu groß für die App-Leiste."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"\"<xliff:g id="NAME">%s</xliff:g>\"-Verknüpfung wurde erstellt."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"\"<xliff:g id="NAME">%s</xliff:g>\"-Verknüpfung wurde entfernt."</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 9eb1e9a..f6c200e 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Συντομεύσεις"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Γραφικά στοιχεία"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Ταπετσαρίες"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Δεν υπάρχει άλλος χώρος στις Αρχικές οθόνες σας."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Δεν υπάρχει άλλος χώρος στο hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Αυτό το γραφικό στοιχείο είναι πολύ μεγάλο για το hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Δημιουργήθηκε η συντόμευση \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Η συντόμευση \"<xliff:g id="NAME">%s</xliff:g>\" καταργήθηκε."</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f00820d..939f1d7 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Shortcuts"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Wallpaper"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"No more room on this Home screen."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"No more room on your Home screens."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"No more room on the hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"This widget is too large for the hot-seat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" created."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" was removed."</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 23b266f..2f8b4cc 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Accesos directos"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Papeles tapiz"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"No hay más espacio en esta pantalla de la página principal"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"No hay más espacio en tu pantalla principal."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"No queda espacio en la barra de accesos directos."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Este widget es demasiado grande para el banquillo."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Acceso directo \"<xliff:g id="NAME">%s</xliff:g>\" creado."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"El acceso directo \"<xliff:g id="NAME">%s</xliff:g>\" ha sido eliminado."</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4458782..86892c2 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Accesos directos"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Fondos de pantalla"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"No queda espacio en el escritorio."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"No queda espacio en las pantallas del escritorio."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"No queda espacio en la barra de accesos directos."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Este widget es demasiado grande para la barra de accesos directos."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Se ha creado el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Se ha eliminado el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 7193149..6262f06 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Otseteed"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Vidinad"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Taustapildid"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Sellel avalehel pole enam ruumi."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Teie avakuvadel ei ole enam ruumi."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Kohandataval dokialal pole rohkem ruumi."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"See vidin on tööpunkti jaoks liiga suur."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Otsetee „<xliff:g id="NAME">%s</xliff:g>” loodud."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Otsetee „<xliff:g id="NAME">%s</xliff:g>” eemaldatud."</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index b596614..7e3f514 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -40,7 +40,10 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"میانبرها"</string>
     <string name="group_widgets" msgid="6704978494073105844">"ابزارک ها"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"تصاویر زمینه"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"اتاق دیگری در این صفحه اصلی موجود نیست."</string>
+    <!-- no translation found for out_of_space (3056555298801463098) -->
+    <skip />
+    <!-- no translation found for hotseat_out_of_space (6304886797358479361) -->
+    <skip />
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"این ابزارک بیش از حد برای صندلی داغ بزرگ است."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"میانبر \"<xliff:g id="NAME">%s</xliff:g>\" ایجاد شد."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"میانبر \"<xliff:g id="NAME">%s</xliff:g>\" حذف شد."</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index c1670d8..59754fd 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Pikakuvakkeet"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgetit"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Taustakuvat"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Etusivulla ei ole enää tilaa."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Aloitusruuduilla ei ole enää tilaa."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Hotseatissa ei ole enää tilaa."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Tämä widget on liian suuri tähän paikkaan."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Pikakuvake <xliff:g id="NAME">%s</xliff:g> luotu"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Pikakuvake <xliff:g id="NAME">%s</xliff:g> poistettiin."</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 6fe1083..312a456 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Raccourcis"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Fonds d\'écran"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Plus d\'espace libre sur l\'écran d\'accueil."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Vous n\'avez plus d\'espace libre sur vos écrans d\'accueil."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Vous n\'avez plus d\'espace libre sur la barre d\'accès rapide."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Ce widget est trop volumineux pour la barre d\'accès rapide."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Le raccourci \"<xliff:g id="NAME">%s</xliff:g>\" a été créé."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Le raccourci \"<xliff:g id="NAME">%s</xliff:g>\" a été supprimé."</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index d44f9c8..4511c31 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"शॉर्टकट"</string>
     <string name="group_widgets" msgid="6704978494073105844">"विजेट"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"वॉलपेपर"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"इस होम स्‍क्रीन पर और स्थान नहीं है."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"आपकी होम स्‍क्रीन पर अधिक स्थान नहीं है."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"हॉटसीट पर अधिक स्‍थान नहीं है."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"हॉटसीट के लि‍ए यह वि‍जेट बहुत बड़ा है."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"\"<xliff:g id="NAME">%s</xliff:g>\" शार्टकट बना दिया गया."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"\"<xliff:g id="NAME">%s</xliff:g>\" शॉर्टकट हटाया गया."</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index a588d5c..8c2051e 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Prečaci"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgeti"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Pozadinske slike"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Na ovom početnom zaslonu više nema mjesta."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Na vašim početnim zaslonima više nema mjesta."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Na hotseatu više nema mjesta."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Ovaj je widget prevelik za hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Izrađen je prečac za \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Prečac za \"<xliff:g id="NAME">%s</xliff:g>\" je uklonjen."</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 1faa884..2912f37 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Parancsikonok"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Modulok"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Háttérképek"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Nincs több hely ezen a főoldalon."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Nincs több hely a Kezdőképernyőkön."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Nincs több hely a hotseaten."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Ez a modul túl nagy a hotseat számára."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"\"<xliff:g id="NAME">%s</xliff:g>\" parancsikon létrehozva."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"A(z) \"<xliff:g id="NAME">%s</xliff:g>\" parancsikon eltávolításra került."</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index dd93a57..ba1c9de 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Pintasan"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Wallpaper"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Tidak ada ruang lagi pada layar Utama ini."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Tidak ada ruang lagi pada layar Utama Anda."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Tidak ada ruang lagi di hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Widget ini terlalu besar untuk hotseat tersebut."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" sudah dibuat."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" telah dihapus."</string>
@@ -60,7 +61,7 @@
     <string name="accessibility_delete_button" msgid="3628162007991023603">"Hapus"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Copot pemasangan pemutakhiran"</string>
     <string name="menu_add" msgid="3065046628354640854">"Tambahkan"</string>
-    <string name="menu_manage_apps" msgid="2308685199463588895">"Mengelola aplikasi"</string>
+    <string name="menu_manage_apps" msgid="2308685199463588895">"Kelola apl"</string>
     <string name="menu_wallpaper" msgid="5837429080911269832">"Wallpaper"</string>
     <string name="menu_search" msgid="4826514464423239041">"Telusuri"</string>
     <string name="menu_notifications" msgid="6424587053194766192">"Pemberitahuan"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 119102c..1a3edbd 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Scorciatoie"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Sfondi"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Spazio nella schermata Home esaurito."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Spazio nelle schermate Home esaurito."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Spazio nell\'area hotseat esaurito."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Questo widget è troppo grande per l\'area hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" creata."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"La scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" è stata rimossa."</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 75cda09..2835105 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"קיצורי דרך"</string>
     <string name="group_widgets" msgid="6704978494073105844">"רכיבי Widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"טפטים"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"אין עוד מקום במסך דף הבית הזה."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"אין יותר מקום במסכי דף הבית."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"אין יותר מקום בפס היישומים."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Widget זה גדול מדי עבור אזור העגינה."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"הקיצור \'<xliff:g id="NAME">%s</xliff:g>\' נוצר."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"הקיצור \'<xliff:g id="NAME">%s</xliff:g>\' הוסר."</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 87ef7c8..f8ff0a7 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"ショートカット"</string>
     <string name="group_widgets" msgid="6704978494073105844">"ウィジェット"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"壁紙"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"ホーム画面に空きスペースがありません。"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"ホーム画面に空きスペースがありません。"</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"ホットシートに空きスペースがありません。"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"このウィジェットはホットシートには大きすぎます。"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"ショートカット「<xliff:g id="NAME">%s</xliff:g>」を作成しました。"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"ショートカット「<xliff:g id="NAME">%s</xliff:g>」を削除しました。"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 6447f13..5a8a2cc 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"바로가기"</string>
     <string name="group_widgets" msgid="6704978494073105844">"위젯"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"배경화면"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"홈 화면에 더 이상 공간이 없습니다."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"홈 화면에 더 이상 공간이 없습니다."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"즐겨찾는 앱 모음에 더 이상 빈 공간이 없습니다."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"이 위젯은 핫시트에 너무 큽니다."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"바로가기(\'<xliff:g id="NAME">%s</xliff:g>\')가 생성되었습니다."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"바로가기(\'<xliff:g id="NAME">%s</xliff:g>\')가 삭제되었습니다."</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 6c19242..4e977e5 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Spartieji klavišai"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Valdikliai"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Darbalaukio fonai"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Šiame pagrindiniame ekrane vietos nebėra."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Pagrindiniuose ekranuose vietos nebėra."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Įtvirtintoje srityje nebėra vietos."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Šis valdiklis per didelis keliems žaidėjams."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Sukurtas „<xliff:g id="NAME">%s</xliff:g>“ spartusis klavišas."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Spartusis klavišas „<xliff:g id="NAME">%s</xliff:g>“ pašalintas."</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 90850ae..fc34d21 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Saīsnes"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Logrīki"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Tapetes"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Šajā sākuma ekrānā vairs nav vietas."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Sākuma ekrānos vairs nav vietas."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Režīmā Hotseat vairs nav vietas."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Šis logrīks ir pārāk liels režīmam “hotseat”."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Saīsne “<xliff:g id="NAME">%s</xliff:g>” tika izveidota."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Saīsne “<xliff:g id="NAME">%s</xliff:g>” tika noņemta."</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index cdcd341..4ea571e 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Pintasan"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Kertas dinding"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Tiada lagi ruang pada skrin Utama ini"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Tiada lagi ruang pada skrin Utama anda."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Tiada lagi ruang pada kerusi panas."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Widget ini terlalu besar untuk kerusi panas."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" diwujudkan."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" telah dialih keluar."</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index f3a7240..1210b05 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Snarveier"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Skrivebordselementer"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Bakgrunner"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Ikke nok plass på skrivebordet."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Ikke mer plass på startsideskjermene."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Dokksonen er full."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Denne modulen er for stor for hotseat-feltet."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Opprettet snarveien «<xliff:g id="NAME">%s</xliff:g>»."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Fjernet snarveien «<xliff:g id="NAME">%s</xliff:g>»."</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 28edf47..b9e5121 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Sneltoetsen"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Achtergronden"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Er is geen ruimte meer op dit startscherm."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Er is geen ruimte meer op uw startschermen."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Er is geen ruimte meer op de hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Deze widget is te groot voor de hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' is gemaakt."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' is verwijderd."</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 3340fa3..e38a887 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Skróty"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widżety"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Tapety"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Brak miejsca na tej stronie głównej"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Brak miejsca na Twoich ekranach głównych."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Brak miejsca w kieszonce."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Ten widżet jest za duży, aby umieścić go w kieszonce."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Skrót „<xliff:g id="NAME">%s</xliff:g>” został utworzony."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Skrót „<xliff:g id="NAME">%s</xliff:g>” został usunięty."</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index ea407b7..4f91467 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Atalhos"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Imagens de fundo"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Não existe espaço suficiente neste ecrã principal."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Sem espaço nos Ecrãs principais."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Não existe espaço suficiente na barra personalizável."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Este widget é demasiado grande para a barra inferior."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi criado."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi removido."</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index a623510..d5657b6 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Atalhos"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Papéis de parede"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Não há mais espaço nesta tela da Página inicial."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Não há mais espaço nas telas iniciais."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Não há mais espaço no hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Este widget é muito grande para o hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Atalho \"<xliff:g id="NAME">%s</xliff:g>\" criado."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi removido."</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index f8f8492..4048e63 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -48,7 +48,10 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Scursanidas"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgets"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Funds davos"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Nagin spazi liber sin il visur da partenza."</string>
+    <!-- no translation found for out_of_space (3056555298801463098) -->
+    <skip />
+    <!-- no translation found for hotseat_out_of_space (6304886797358479361) -->
+    <skip />
     <!-- no translation found for invalid_hotseat_item (6545340627805449250) -->
     <skip />
     <string name="shortcut_installed" msgid="7071557296331322355">"\"Creà ina scursanida \"\"<xliff:g id="NAME">%s</xliff:g>\"\".\""</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 2d3a018..3d46177 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Comenzi rapide"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Obiecte widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Imagini de fundal"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Niciun spaţiu rămas pe acest Ecran de pornire."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Nu mai este loc pe ecranele de pornire."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Nu mai există loc în bara de lansare rapidă."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Acest widget este prea mare pentru hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Comanda rapidă „<xliff:g id="NAME">%s</xliff:g>”·a fost creată."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Comanda rapidă „<xliff:g id="NAME">%s</xliff:g>” a fost eliminată."</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0394a04..0557447 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Ярлыки"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Виджеты"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Обои"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"На этом экране всё занято."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"На главных экранах всё занято."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Нет свободного места в слоте."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Виджет слишком велик для слота."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Ярлык \"<xliff:g id="NAME">%s</xliff:g>\" создан"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Ярлык \"<xliff:g id="NAME">%s</xliff:g>\" удален."</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index b5f8814..a9648fd 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Odkazy"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Miniaplikácie"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Tapety"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Na tejto ploche už nie je miesto"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Na plochách už nie je miesto."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"V časti hotseat už nie je miesto."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Táto miniaplikácia je pre hotseat príliš veľká."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Odkaz <xliff:g id="NAME">%s</xliff:g> bol vytvorený."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Odkaz <xliff:g id="NAME">%s</xliff:g> bol odstránený."</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index c9b2e04..4b64f0a 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Bližnjice"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Pripomočki"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Slike za ozadje"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Na tem začetnem zaslonu ni več prostora."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Na začetnih zaslonih ni več prostora."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"V vrstici z ikonami ni več prostora."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Ta pripomoček je prevelik za podnožje."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Bližnjica »<xliff:g id="NAME">%s</xliff:g>« je bila ustvarjena."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Bližnjica »<xliff:g id="NAME">%s</xliff:g>« je bila odstranjena."</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 5dbfeab..d0ee441 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Пречице"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Виџети"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Позадине"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Нема више простора на овом почетном екрану."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Нема више простора на Почетним екранима."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Нема више простора на траци актуелности."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Овај виџет је превелики за траку актуелности."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Пречица „<xliff:g id="NAME">%s</xliff:g>“ је направљена."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Пречица „<xliff:g id="NAME">%s</xliff:g>“ је уклоњена."</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 9026922..0d98de8 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Genvägar"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widgetar"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Bakgrundsbilder"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Det finns inte plats för mer på den här startsidan."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Det finns inte plats för mer på dina startsidor."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Utrymmet på Hotseat är fullt."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Denna widget är för stor för Hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Genvägen \"<xliff:g id="NAME">%s</xliff:g>\" har skapats."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Genvägen \"<xliff:g id="NAME">%s</xliff:g>\" har tagits bort."</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 1e928ed..0fc2a5a 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Njia za mkato"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Wijeti"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Mandhari"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Hakuna nafasi katika skrini hii ya nyumbani."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Hakuna nafasi zaidi kwenye skrini zako za nyumbani."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Hakuna nafasi zaidi kwenye eneo kali."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Wijeti hii ni kubwa zaidi kwa hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Njia ya mkato ya \"<xliff:g id="NAME">%s</xliff:g>\" imeundwa."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Njia ya mkato ya \"<xliff:g id="NAME">%s</xliff:g>\" iliondolewa."</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 3bcc144..e832972 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"ทางลัด"</string>
     <string name="group_widgets" msgid="6704978494073105844">"วิดเจ็ต"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"วอลเปเปอร์"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"ไม่มีที่ว่างในหน้าจอหลักนี้"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"ไม่มีที่ว่างในหน้าจอหลักของคุณ"</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"ไม่มีที่ว่างใน hotseat"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"วิดเจ็ตนี้มีขนาดใหญ่เกินไปสำหรับ hotseat"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"สร้างทางลัด \"<xliff:g id="NAME">%s</xliff:g>\" แล้ว"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"ทางลัด \"<xliff:g id="NAME">%s</xliff:g>\" ถูกนำออกแล้ว"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index e315cd8..a20ca09 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Mga Shortcut"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Mga Widget"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Mga Wallpaper"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Wala nang lugar sa Home screen na ito."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Wala nang puwang sa iyong mga Home screen."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Wala nang lugar sa hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Masyadong malaki ang widget na ito para sa hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Nalikha ang shortcut na \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Inalis ang shortcut na \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index fef4df5..28de742 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Kısayollar"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Widget\'lar"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Duvar Kağıtları"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Bu Ana Sayfada yer yok."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Ana ekranlarınızda başka yer kalmadı."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Favori kısa yollarda yer yok"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Bu widget, hotseat için çok büyük."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu oluşturuldu."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu kaldırıldı."</string>
@@ -89,9 +90,9 @@
     <string name="apps_customize_apps_scroll_format" msgid="5494241912377704885">"Uygulama sayfası %1$d / %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="5383009742241717437">"Widget sayfası %1$d / %2$d"</string>
     <string name="workspace_cling_title" msgid="738396473989890567">"Kendinizi evinizde hissedin"</string>
-    <string name="workspace_cling_move_item" msgid="791013895761065070">"Farvori uygulamalarınızı buraya koyabilirsiniz."</string>
+    <string name="workspace_cling_move_item" msgid="791013895761065070">"Favori uygulamalarınızı buraya koyabilirsiniz."</string>
     <string name="workspace_cling_open_all_apps" msgid="2459977609848572588">"Tüm uygulamalarınızı görmek için çembere dokunun."</string>
-    <string name="all_apps_cling_title" msgid="2559734712581447107">"Bazı uygulamalar seçin"</string>
+    <string name="all_apps_cling_title" msgid="2559734712581447107">"İstediğiniz uygulamaları seçin"</string>
     <string name="all_apps_cling_add_item" msgid="5665035103260318891">"Ana Ekranınıza bir uygulama eklemek için, ilgili uygulamaya dokunup basılı tutun."</string>
     <string name="folder_cling_title" msgid="4308949882377840953">"Uygulamalarınızı klasörlerle düzenleyin"</string>
     <string name="folder_cling_move_item" msgid="270598675060435169">"Bir uygulamayı taşımak için, uygulamaya dokunun ve basılı tutun."</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 0ee1529..7426a74 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Ярлики"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Віджети"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Фонові мал."</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Немає більше місця на гол. екрані."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"На головних екранах більше немає місця."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"На гарячій панелі більше немає місця."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Цей віджет завеликий для Hotseat."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" створено."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" видалено."</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 544c8a4..c19a9d8 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Lối tắt"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Tiện ích"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Hình nền"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Không còn khoảng trống trên Màn hình chính này."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Không còn chỗ trên màn hình chính của bạn."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Không còn chỗ trên vùng gắn."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Tiện ích này quá lớn cho điểm giới hạn."</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Lối tắt \"<xliff:g id="NAME">%s</xliff:g>\" đã được tạo."</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Lối tắt \"<xliff:g id="NAME">%s</xliff:g>\" đã bị xóa."</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 81525cf..7c30da4 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -20,12 +20,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="application_name" msgid="8424725141379931883">"启动器"</string>
-    <string name="uid_name" msgid="3371120195364560632">"Android 核心应用程序"</string>
+    <string name="uid_name" msgid="3371120195364560632">"Android 核心应用"</string>
     <string name="folder_name" msgid="8551881338202938211"></string>
     <string name="chooser_wallpaper" msgid="6063168087625352235">"选择壁纸来源"</string>
     <string name="wallpaper_instructions" msgid="4215640646180727542">"设置壁纸"</string>
     <string name="pick_wallpaper" msgid="5630222540525626723">"壁纸"</string>
-    <string name="activity_not_found" msgid="217823393239365967">"未安装该应用程序。"</string>
+    <string name="activity_not_found" msgid="217823393239365967">"未安装该应用。"</string>
     <string name="widgets_tab_label" msgid="9145860100000983599">"窗口小部件"</string>
     <string name="long_press_widget_to_add" msgid="7395697462851217506">"触摸并按住可选取窗口小部件。"</string>
     <string name="market" msgid="2652226429823445833">"购买"</string>
@@ -36,66 +36,67 @@
     <string name="rename_action" msgid="6016003384693240896">"确定"</string>
     <string name="cancel_action" msgid="3811860427489435048">"取消"</string>
     <string name="menu_item_add_item" msgid="6233177331075781114">"添加到主屏幕"</string>
-    <string name="group_applications" msgid="2103752818818161976">"应用程序"</string>
+    <string name="group_applications" msgid="2103752818818161976">"应用"</string>
     <string name="group_shortcuts" msgid="9133529424900391877">"快捷方式"</string>
     <string name="group_widgets" msgid="6704978494073105844">"窗口小部件"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"壁纸"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"此主屏幕上已没有空间。"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"您的主屏幕上没有空间了。"</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"底部区域已无空间。"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"该窗口小部件太大,超出基座区域可用空间。"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"已创建“<xliff:g id="NAME">%s</xliff:g>”快捷方式。"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"已删除“<xliff:g id="NAME">%s</xliff:g>”快捷方式。"</string>
     <string name="shortcut_duplicate" msgid="4757756326465060694">"“<xliff:g id="NAME">%s</xliff:g>”快捷方式已存在。"</string>
     <string name="title_select_shortcut" msgid="1873670208166882222">"选择快捷方式"</string>
-    <string name="title_select_application" msgid="1793455815754848652">"选择应用程序"</string>
-    <string name="all_apps_button_label" msgid="2578400570124163469">"应用程序"</string>
+    <string name="title_select_application" msgid="1793455815754848652">"选择应用"</string>
+    <string name="all_apps_button_label" msgid="2578400570124163469">"应用"</string>
     <string name="all_apps_home_button_label" msgid="1022222300329398558">"主屏幕"</string>
     <string name="delete_zone_label_workspace" msgid="7153615831493049150">"删除"</string>
     <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"卸载"</string>
     <string name="delete_target_label" msgid="665300185123139530">"删除"</string>
     <string name="delete_target_uninstall_label" msgid="748894921183769150">"卸载"</string>
-    <string name="info_target_label" msgid="4019495079517426980">"应用程序信息"</string>
+    <string name="info_target_label" msgid="4019495079517426980">"应用信息"</string>
     <string name="accessibility_search_button" msgid="816822994629942611">"搜索"</string>
     <string name="accessibility_voice_search_button" msgid="3938249215065842475">"语音搜索"</string>
-    <string name="accessibility_all_apps_button" msgid="8803738611398979849">"应用程序"</string>
+    <string name="accessibility_all_apps_button" msgid="8803738611398979849">"应用"</string>
     <string name="accessibility_delete_button" msgid="3628162007991023603">"删除"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"卸载更新"</string>
     <string name="menu_add" msgid="3065046628354640854">"添加"</string>
-    <string name="menu_manage_apps" msgid="2308685199463588895">"管理应用程序"</string>
+    <string name="menu_manage_apps" msgid="2308685199463588895">"管理应用"</string>
     <string name="menu_wallpaper" msgid="5837429080911269832">"壁纸"</string>
     <string name="menu_search" msgid="4826514464423239041">"搜索"</string>
     <string name="menu_notifications" msgid="6424587053194766192">"通知"</string>
     <string name="menu_settings" msgid="3946232973327980394">"系统设置"</string>
     <string name="menu_help" msgid="4901160661634590633">"帮助"</string>
-    <string name="cab_menu_delete_app" msgid="4089398025537640349">"卸载该应用程序"</string>
-    <string name="cab_menu_app_info" msgid="914548323652698884">"应用程序详情"</string>
-    <string name="cab_app_selection_text" msgid="6378522164293415735">"选中了 1 个应用程序"</string>
+    <string name="cab_menu_delete_app" msgid="4089398025537640349">"卸载该应用"</string>
+    <string name="cab_menu_app_info" msgid="914548323652698884">"应用详情"</string>
+    <string name="cab_app_selection_text" msgid="6378522164293415735">"选中了 1 个应用"</string>
     <string name="cab_widget_selection_text" msgid="962527270506951955">"已选中 1 个窗口小部件"</string>
     <string name="cab_folder_selection_text" msgid="8916111874189565067">"已选中 1 个文件夹"</string>
     <string name="cab_shortcut_selection_text" msgid="8115847384500412878">"已选中 1 个快捷方式"</string>
     <string name="permlab_install_shortcut" msgid="1201690825493376489">"安装快捷方式"</string>
-    <string name="permdesc_install_shortcut" msgid="8634424803272077038">"允许应用程序自行添加快捷方式。"</string>
+    <string name="permdesc_install_shortcut" msgid="8634424803272077038">"允许应用自行添加快捷方式。"</string>
     <string name="permlab_uninstall_shortcut" msgid="7696645932555926449">"卸载快捷方式"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="274355570620220977">"允许应用程序自行删除快捷方式,而无需用户干预。"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="274355570620220977">"允许应用自行删除快捷方式,而无需用户干预。"</string>
     <string name="permlab_read_settings" msgid="3452408290738106747">"读取主屏幕的设置和快捷方式"</string>
-    <string name="permdesc_read_settings" msgid="5788109303585403679">"允许应用程序读取主屏幕中的设置和快捷方式。"</string>
+    <string name="permdesc_read_settings" msgid="5788109303585403679">"允许应用读取主屏幕中的设置和快捷方式。"</string>
     <string name="permlab_write_settings" msgid="1360567537236705628">"写入主屏幕的设置和快捷方式"</string>
-    <string name="permdesc_write_settings" msgid="8530105489115785531">"允许应用程序更改主屏幕中的设置和快捷方式。"</string>
+    <string name="permdesc_write_settings" msgid="8530105489115785531">"允许应用更改主屏幕中的设置和快捷方式。"</string>
     <string name="gadget_error_text" msgid="8359351016167075858">"载入窗口小部件时出现问题"</string>
-    <string name="uninstall_system_app_text" msgid="6429814133777046491">"这是系统应用程序,无法卸载。"</string>
+    <string name="uninstall_system_app_text" msgid="6429814133777046491">"这是系统应用,无法卸载。"</string>
     <string name="dream_name" msgid="2847171357608437154">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="8633351560105748141">"未命名文件夹"</string>
     <string name="default_scroll_format" msgid="4057140866420001240">"第 %1$d 页,共 %2$d 页"</string>
     <string name="workspace_scroll_format" msgid="7911126267695001437">"工作区:第 %1$d 页,共 %2$d 页"</string>
-    <string name="apps_customize_apps_scroll_format" msgid="5494241912377704885">"应用程序:第 %1$d 页,共 %2$d 页"</string>
+    <string name="apps_customize_apps_scroll_format" msgid="5494241912377704885">"应用:第 %1$d 页,共 %2$d 页"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="5383009742241717437">"窗口小部件:第 %1$d 页,共 %2$d 页"</string>
     <string name="workspace_cling_title" msgid="738396473989890567">"随意浏览"</string>
-    <string name="workspace_cling_move_item" msgid="791013895761065070">"您可以在此处放置自己喜爱的应用程序。"</string>
-    <string name="workspace_cling_open_all_apps" msgid="2459977609848572588">"要查看您的所有应用程序,请触摸该圆圈。"</string>
-    <string name="all_apps_cling_title" msgid="2559734712581447107">"选择一些应用程序"</string>
-    <string name="all_apps_cling_add_item" msgid="5665035103260318891">"要将某个应用程序添加到主屏幕,请触摸并按住该应用程序。"</string>
-    <string name="folder_cling_title" msgid="4308949882377840953">"使用文件夹整理应用程序"</string>
-    <string name="folder_cling_move_item" msgid="270598675060435169">"要移动应用程序,请触摸并按住该应用程序。"</string>
-    <string name="folder_cling_create_folder" msgid="8352867485656129478">"要在主屏幕上创建新文件夹,请将一个应用程序叠放到另一个上。"</string>
+    <string name="workspace_cling_move_item" msgid="791013895761065070">"您可以在此处放置自己喜爱的应用。"</string>
+    <string name="workspace_cling_open_all_apps" msgid="2459977609848572588">"要查看您的所有应用,请触摸该圆圈。"</string>
+    <string name="all_apps_cling_title" msgid="2559734712581447107">"选择一些应用"</string>
+    <string name="all_apps_cling_add_item" msgid="5665035103260318891">"要将某个应用添加到主屏幕,请触摸并按住该应用。"</string>
+    <string name="folder_cling_title" msgid="4308949882377840953">"使用文件夹整理应用"</string>
+    <string name="folder_cling_move_item" msgid="270598675060435169">"要移动应用,请触摸并按住该应用。"</string>
+    <string name="folder_cling_create_folder" msgid="8352867485656129478">"要在主屏幕上创建新文件夹,请将一个应用叠放到另一个上。"</string>
     <string name="cling_dismiss" msgid="2780907108735868381">"确定"</string>
     <string name="folder_opened" msgid="1262064100943801533">"文件夹已打开,尺寸为 <xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="1335478160661137579">"触摸可关闭文件夹"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8ad516e..00eeaf1 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"捷徑"</string>
     <string name="group_widgets" msgid="6704978494073105844">"小工具"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"桌布"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"主螢幕已無空間"</string>
+    <string name="out_of_space" msgid="3056555298801463098">"主螢幕已無空間。"</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"停駐區已無可用空間。"</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"這個小工具過大,超出可用的空間。"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"已建立「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"已移除「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index a68675d..8855db5 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -40,7 +40,8 @@
     <string name="group_shortcuts" msgid="9133529424900391877">"Izinqamuleli"</string>
     <string name="group_widgets" msgid="6704978494073105844">"Izinqunjwana"</string>
     <string name="group_wallpapers" msgid="1568191644272224858">"Amaphephadonga"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Asisekho isikhala kulesi sikrini Sasekhaya."</string>
+    <string name="out_of_space" msgid="3056555298801463098">"Akusenagumbi ezikrinini zakho zekhaya."</string>
+    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Akusenagumbi ku-hotseat."</string>
     <string name="invalid_hotseat_item" msgid="6545340627805449250">"Le wijethi inkulu kakhulu ukuba ibe esihlalweni esishisayo"</string>
     <string name="shortcut_installed" msgid="7071557296331322355">"Isinqamuleli \"<xliff:g id="NAME">%s</xliff:g>\" senziwe"</string>
     <string name="shortcut_uninstalled" msgid="2129499669449749995">"Isinqamuleli \"<xliff:g id="NAME">%s</xliff:g>\" sikhishiwe."</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a9b14d0..f707c8c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -82,7 +82,9 @@
     <!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
     <string name="group_wallpapers">Wallpapers</string>
     <!-- Error message when user has filled a home screen, possibly not used -->
-    <string name="out_of_space">No more room on this Home screen.</string>
+    <string name="out_of_space">No more room on your Home screens.</string>
+    <!-- Error message when user has filled the hotseat -->
+    <string name="hotseat_out_of_space">No more room on the hotseat.</string>
     <!-- Error message when user tries to drop an invalid item on the hotseat -->
     <string name="invalid_hotseat_item">This widget is too large for the hotseat.</string>
     <!-- Message displayed when a shortcut is created by an external application -->
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 1a9958c..840ec45 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -725,9 +725,14 @@
         return true;
     }
 
-    private void endDragging(View target, boolean success) {
+    /**
+     * Clean up after dragging.
+     *
+     * @param target where the item was dragged to (can be null if the item was flung)
+     */
+    private void endDragging(View target, boolean isFlingToDelete, boolean success) {
         mLauncher.getWorkspace().onDragStopped(success);
-        if (!success || (target != mLauncher.getWorkspace() &&
+        if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
                 !(target instanceof DeleteDropTarget))) {
             // Exit spring loaded mode if we have not successfully dropped or have not handled the
             // drop in Workspace
@@ -763,8 +768,12 @@
     }
 
     @Override
-    public void onDropCompleted(View target, DragObject d, boolean success) {
-        endDragging(target, success);
+    public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
+            boolean success) {
+        // Return early and wait for onFlingToDeleteCompleted if this was the result of a fling
+        if (isFlingToDelete) return;
+
+        endDragging(target, false, success);
 
         // Display an error message if the drag failed due to there not being enough space on the
         // target layout we were dropping on.
@@ -782,7 +791,7 @@
                 }
             }
             if (showOutOfSpaceMessage) {
-                mLauncher.showOutOfSpaceMessage();
+                mLauncher.showOutOfSpaceMessage(false);
             }
 
             d.deferDragViewCleanupPostAnimation = false;
@@ -791,8 +800,17 @@
         mDraggingWidget = false;
     }
 
+    @Override
+    public void onFlingToDeleteCompleted() {
+        // We just dismiss the drag when we fling, so cleanup here
+        endDragging(null, true, true);
+        cleanupWidgetPreloading();
+        mDraggingWidget = false;
+    }
+
+    @Override
     public boolean supportsFlingToDelete() {
-        return false;
+        return true;
     }
 
     @Override
@@ -1089,6 +1107,8 @@
             bitmapWidth = drawable.getIntrinsicWidth();
             bitmapHeight = drawable.getIntrinsicHeight();
         } else {
+            if (cellHSpan < 1) cellHSpan = 1;
+            if (cellVSpan < 1) cellVSpan = 1;
             // Determine the size of the bitmap for the preview image we will generate
             // TODO: This actually uses the apps customize cell layout params, where as we make want
             // the Workspace params for more accuracy.
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 5969f98..199c41a 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -18,8 +18,6 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
@@ -59,6 +57,7 @@
 public class CellLayout extends ViewGroup {
     static final String TAG = "CellLayout";
 
+    private Launcher mLauncher;
     private int mOriginalCellWidth;
     private int mOriginalCellHeight;
     private int mCellWidth;
@@ -129,12 +128,15 @@
 
     private HashMap<CellLayout.LayoutParams, Animator> mReorderAnimators = new
             HashMap<CellLayout.LayoutParams, Animator>();
+    private HashMap<View, ReorderHintAnimation>
+            mShakeAnimators = new HashMap<View, ReorderHintAnimation>();
+
+    private boolean mItemPlacementDirty = false;
 
     // When a drag operation is in progress, holds the nearest cell to the touch point
     private final int[] mDragCell = new int[2];
 
     private boolean mDragging = false;
-    private boolean mItemLocationsDirty = false;
 
     private TimeInterpolator mEaseOutInterpolator;
     private ShortcutAndWidgetContainer mShortcutsAndWidgets;
@@ -147,12 +149,18 @@
     public static final int MODE_ON_DROP = 1;
     public static final int MODE_ON_DROP_EXTERNAL = 2;
     public static final int MODE_ACCEPT_DROP = 3;
-    private static final boolean DESTRUCTIVE_REORDER = true;
+    private static final boolean DESTRUCTIVE_REORDER = false;
     private static final boolean DEBUG_VISUALIZE_OCCUPIED = false;
 
+    private static final float REORDER_HINT_MAGNITUDE = 0.27f;
+    private static final int REORDER_ANIMATION_DURATION = 150;
+    private float mReorderHintAnimationMagnitude;
+
     private ArrayList<View> mIntersectingViews = new ArrayList<View>();
     private Rect mOccupiedRect = new Rect();
     private int[] mDirectionVector = new int[2];
+    int[] mPreviousReorderDirection = new int[2];
+    private static final int INVALID_DIRECTION = -100;
 
     public CellLayout(Context context) {
         this(context, null);
@@ -168,6 +176,7 @@
         // A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
         // the user where a dragged item will land when dropped.
         setWillNotDraw(false);
+        mLauncher = (Launcher) context;
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
 
@@ -182,6 +191,8 @@
         mCountY = LauncherModel.getCellCountY();
         mOccupied = new boolean[mCountX][mCountY];
         mTmpOccupied = new boolean[mCountX][mCountY];
+        mPreviousReorderDirection[0] = INVALID_DIRECTION;
+        mPreviousReorderDirection[1] = INVALID_DIRECTION;
 
         a.recycle();
 
@@ -197,6 +208,9 @@
         mForegroundPadding =
                 res.getDimensionPixelSize(R.dimen.workspace_overscroll_drawable_padding);
 
+        mReorderHintAnimationMagnitude = (REORDER_HINT_MAGNITUDE *
+                res.getDimensionPixelSize(R.dimen.app_icon_size));
+
         mNormalBackground.setFilterBitmap(true);
         mActiveGlowBackground.setFilterBitmap(true);
 
@@ -317,6 +331,7 @@
         mCountY = y;
         mOccupied = new boolean[mCountX][mCountY];
         mTmpOccupied = new boolean[mCountX][mCountY];
+        mTempRectStack.clear();
         requestLayout();
     }
 
@@ -611,8 +626,6 @@
                 (bubbleChild.getMeasuredWidth() | bubbleChild.getMeasuredHeight()) == 0) {
             getShortcutsAndWidgets().measureChild(bubbleChild);
         }
-        int measuredWidth = bubbleChild.getMeasuredWidth();
-        int measuredHeight = bubbleChild.getMeasuredHeight();
 
         bubbleChild.setScaleX(scale);
         bubbleChild.setScaleY(scale);
@@ -887,13 +900,28 @@
     void regionToCenterPoint(int cellX, int cellY, int spanX, int spanY, int[] result) {
         final int hStartPadding = getPaddingLeft();
         final int vStartPadding = getPaddingTop();
-
         result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap) +
                 (spanX * mCellWidth + (spanX - 1) * mWidthGap) / 2;
         result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap) +
                 (spanY * mCellHeight + (spanY - 1) * mHeightGap) / 2;
     }
 
+     /**
+     * Given a cell coordinate and span fills out a corresponding pixel rect
+     *
+     * @param cellX X coordinate of the cell
+     * @param cellY Y coordinate of the cell
+     * @param result Rect in which to write the result
+     */
+     void regionToRect(int cellX, int cellY, int spanX, int spanY, Rect result) {
+        final int hStartPadding = getPaddingLeft();
+        final int vStartPadding = getPaddingTop();
+        final int left = hStartPadding + cellX * (mCellWidth + mWidthGap);
+        final int top = vStartPadding + cellY * (mCellHeight + mHeightGap);
+        result.set(left, top, left + (spanX * mCellWidth + (spanX - 1) * mWidthGap),
+                top + (spanY * mCellHeight + (spanY - 1) * mHeightGap));
+    }
+
     public float getDistanceFromCell(float x, float y, int[] cell) {
         cellToCenterPoint(cell[0], cell[1], mTmpPoint);
         float distance = (float) Math.sqrt( Math.pow(x - mTmpPoint[0], 2) +
@@ -1055,7 +1083,7 @@
             occupied = mTmpOccupied;
         }
 
-        if (clc.indexOfChild(child) != -1 && !occupied[cellX][cellY]) {
+        if (clc.indexOfChild(child) != -1) {
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             final ItemInfo info = (ItemInfo) child.getTag();
 
@@ -1101,8 +1129,9 @@
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float r = ((Float) animation.getAnimatedValue()).floatValue();
-                    child.setTranslationX(r * (newX - oldX));
-                    child.setTranslationY(r * (newY - oldY));
+                    lp.x = (int) ((1 - r) * oldX + r * newX);
+                    lp.y = (int) ((1 - r) * oldY + r * newY);
+                    child.requestLayout();
                 }
             });
             va.addListener(new AnimatorListenerAdapter() {
@@ -1112,8 +1141,6 @@
                     // has interrupted this one, and we don't want to lock the item into
                     // place just yet.
                     if (!cancelled) {
-                        child.setTranslationX(0);
-                        child.setTranslationY(0);
                         lp.isLockedToGrid = true;
                         child.requestLayout();
                     }
@@ -1541,7 +1568,8 @@
         float bestDistance = Float.MAX_VALUE;
 
         // We use this to march in a single direction
-        if (direction[0] != 0 && direction[1] != 0) { 
+        if ((direction[0] != 0 && direction[1] != 0) ||
+                (direction[0] == 0 && direction[1] == 0)) {
             return bestXY;
         }
 
@@ -1574,31 +1602,28 @@
     }
 
     private boolean addViewToTempLocation(View v, Rect rectOccupiedByPotentialDrop,
-            int[] direction) {
-        LayoutParams lp = (LayoutParams) v.getLayoutParams();
+            int[] direction, ItemConfiguration currentState) {
+        CellAndSpan c = currentState.map.get(v);
         boolean success = false;
-        markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                lp.cellVSpan, mTmpOccupied, false);
+        markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, false);
         markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
 
-        findNearestArea(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan, lp.cellVSpan,
-                direction, mTmpOccupied, null, mTempLocation);
+        findNearestArea(c.x, c.y, c.spanX, c.spanY, direction, mTmpOccupied, null, mTempLocation);
 
         if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
-            lp.tmpCellX = mTempLocation[0];
-            lp.tmpCellY = mTempLocation[1];
+            c.x = mTempLocation[0];
+            c.y = mTempLocation[1];
             success = true;
 
         }
-        markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                lp.cellVSpan, mTmpOccupied, true);
+        markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
         return success;
     }
 
     // This method looks in the specified direction to see if there is an additional view
     // immediately adjecent in that direction
     private boolean addViewInDirection(ArrayList<View> views, Rect boundingRect, int[] direction,
-            boolean[][] occupied) {
+            boolean[][] occupied, View dragView, ItemConfiguration currentState) {
         boolean found = false;
 
         int childCount = mShortcutsAndWidgets.getChildCount();
@@ -1623,17 +1648,18 @@
 
         for (int i = 0; i < childCount; i++) {
             View child = mShortcutsAndWidgets.getChildAt(i);
-            if (views.contains(child)) continue;
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (views.contains(child) || child == dragView) continue;
+            CellAndSpan c = currentState.map.get(child);
 
-            r1.set(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan, lp.tmpCellY + lp.cellVSpan);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            r1.set(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
             if (Rect.intersects(r0, r1)) {
                 if (!lp.canReorder) {
                     return false;
                 }
                 boolean pushed = false;
-                for (int x = lp.tmpCellX; x < lp.tmpCellX + lp.cellHSpan; x++) {
-                    for (int y = lp.tmpCellY; y < lp.tmpCellY + lp.cellVSpan; y++) {
+                for (int x = c.x; x < c.x + c.spanX; x++) {
+                    for (int y = c.y; y < c.y + c.spanY; y++) {
                         boolean inBounds = x - deltaX >= 0 && x -deltaX < mCountX
                                 && y - deltaY >= 0 && y - deltaY < mCountY;
                         if (inBounds && occupied[x - deltaX][y - deltaY]) {
@@ -1643,8 +1669,7 @@
                 }
                 if (pushed) {
                     views.add(child);
-                    boundingRect.union(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
-                            lp.tmpCellY + lp.cellVSpan);
+                    boundingRect.union(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
                     found = true;
                 }
             }
@@ -1652,116 +1677,72 @@
         return found;
     }
 
-    private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
-            int[] direction) {
-        if (views.size() == 0) return true;
-
-
-        boolean success = false;
-
-        // We construct a rect which represents the entire group of views
-        Rect boundingRect = null;
-        for (View v: views) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            if (boundingRect == null) {
-                boundingRect = new Rect(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
-                        lp.tmpCellY + lp.cellVSpan);
-            } else {
-                boundingRect.union(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
-                        lp.tmpCellY + lp.cellVSpan);
-            }
-        }
-
-        ArrayList<View> dup = (ArrayList<View>) views.clone();
-        while (addViewInDirection(dup, boundingRect, direction, mTmpOccupied)) {
-        }
-        for (View v: dup) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                    lp.cellVSpan, mTmpOccupied, false); 
-        }
-
-        boolean[][] blockOccupied = new boolean[boundingRect.width()][boundingRect.height()];
-        int top = boundingRect.top;
-        int left = boundingRect.left;
-        for (View v: dup) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX - left, lp.tmpCellY - top, lp.cellHSpan,
-                    lp.cellVSpan, blockOccupied, true); 
-        }
-
-        markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
-
-        findNearestAreaInDirection(boundingRect.left, boundingRect.top, boundingRect.width(),
-                boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
-
-        int deltaX = mTempLocation[0] - boundingRect.left;
-        int deltaY = mTempLocation[1] - boundingRect.top;
-        if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
-            for (View v: dup) {
-                LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                lp.tmpCellX += deltaX;
-                lp.tmpCellY += deltaY;
-            }
-            success = true;
-        }
-        for (View v: dup) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                    lp.cellVSpan, mTmpOccupied, true);
-        }
-        return success;
-    }
-
     private boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
-            int[] direction) {
+            int[] direction, boolean push, View dragView, ItemConfiguration currentState) {
         if (views.size() == 0) return true;
-        boolean success = false;
 
-        // We construct a rect which represents the entire group of views
+        boolean success = false;
         Rect boundingRect = null;
+        // We construct a rect which represents the entire group of views passed in
         for (View v: views) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                    lp.cellVSpan, mTmpOccupied, false);
+            CellAndSpan c = currentState.map.get(v);
             if (boundingRect == null) {
-                boundingRect = new Rect(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
-                        lp.tmpCellY + lp.cellVSpan);
+                boundingRect = new Rect(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
             } else {
-                boundingRect.union(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
-                        lp.tmpCellY + lp.cellVSpan);
+                boundingRect.union(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
             }
         }
+
+        @SuppressWarnings("unchecked")
+        ArrayList<View> dup = (ArrayList<View>) views.clone();
+        // We try and expand the group of views in the direction vector passed, based on
+        // whether they are physically adjacent, ie. based on "push mechanics".
+        while (push && addViewInDirection(dup, boundingRect, direction, mTmpOccupied, dragView,
+                currentState)) {
+        }
+
+        // Mark the occupied state as false for the group of views we want to move.
+        for (View v: dup) {
+            CellAndSpan c = currentState.map.get(v);
+            markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, false);
+        }
+
         boolean[][] blockOccupied = new boolean[boundingRect.width()][boundingRect.height()];
         int top = boundingRect.top;
         int left = boundingRect.left;
-        for (View v: views) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX - left, lp.tmpCellY - top, lp.cellHSpan,
-                    lp.cellVSpan, blockOccupied, true); 
+        // We mark more precisely which parts of the bounding rect are truly occupied, allowing
+        // for tetris-style interlocking.
+        for (View v: dup) {
+            CellAndSpan c = currentState.map.get(v);
+            markCellsForView(c.x - left, c.y - top, c.spanX, c.spanY, blockOccupied, true);
         }
 
         markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
 
-        // TODO: this bounding rect may not be completely filled, lets be more precise about this
-        // check.
-        findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(),
-                boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
+        if (push) {
+            findNearestAreaInDirection(boundingRect.left, boundingRect.top, boundingRect.width(),
+                    boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
+        } else {
+            findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(),
+                    boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
+        }
 
-        int deltaX = mTempLocation[0] - boundingRect.left;
-        int deltaY = mTempLocation[1] - boundingRect.top;
+        // If we successfuly found a location by pushing the block of views, we commit it
         if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
-            for (View v: views) {
-                LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                lp.tmpCellX += deltaX;
-                lp.tmpCellY += deltaY;
+            int deltaX = mTempLocation[0] - boundingRect.left;
+            int deltaY = mTempLocation[1] - boundingRect.top;
+            for (View v: dup) {
+                CellAndSpan c = currentState.map.get(v);
+                c.x += deltaX;
+                c.y += deltaY;
             }
             success = true;
         }
-        for (View v: views) {
-            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-            markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
-                    lp.cellVSpan, mTmpOccupied, true);
+
+        // In either case, we set the occupied array as marked for the location of the views
+        for (View v: dup) {
+            CellAndSpan c = currentState.map.get(v);
+            markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
         }
         return success;
     }
@@ -1771,25 +1752,26 @@
     }
 
     private boolean rearrangementExists(int cellX, int cellY, int spanX, int spanY, int[] direction,
-            View ignoreView) {
-        mIntersectingViews.clear();
+            View ignoreView, ItemConfiguration solution) {
 
+        mIntersectingViews.clear();
         mOccupiedRect.set(cellX, cellY, cellX + spanX, cellY + spanY);
 
+        // Mark the desired location of the view currently being dragged.
         if (ignoreView != null) {
-            LayoutParams lp = (LayoutParams) ignoreView.getLayoutParams();
-            lp.tmpCellX = cellX;
-            lp.tmpCellY = cellY;
+            CellAndSpan c = solution.map.get(ignoreView);
+            if (c != null) {
+                c.x = cellX;
+                c.y = cellY;
+            }
         }
-
-        int childCount = mShortcutsAndWidgets.getChildCount();
         Rect r0 = new Rect(cellX, cellY, cellX + spanX, cellY + spanY);
         Rect r1 = new Rect();
-        for (int i = 0; i < childCount; i++) {
-            View child = mShortcutsAndWidgets.getChildAt(i);
+        for (View child: solution.map.keySet()) {
             if (child == ignoreView) continue;
+            CellAndSpan c = solution.map.get(child);
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            r1.set(lp.cellX, lp.cellY, lp.cellX + lp.cellHSpan, lp.cellY + lp.cellVSpan);
+            r1.set(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
             if (Rect.intersects(r0, r1)) {
                 if (!lp.canReorder) {
                     return false;
@@ -1798,27 +1780,31 @@
             }
         }
 
-        if (pushViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
+        // We try to move the intersecting views as a block using the push mechanic
+        if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, true, ignoreView,
+                solution)) {
             return true;
         }
         // Try the opposite direction
         direction[0] *= -1;
         direction[1] *= -1;
-        if (pushViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
+        if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, true, ignoreView,
+                solution)) {
             return true;
         }
         // Switch the direction back
         direction[0] *= -1;
         direction[1] *= -1;
 
-        // First we try moving the views as a block
-        if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
+        // Next we try moving the views as a block , but without requiring the push mechanic
+        if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, false, ignoreView,
+                solution)) {
             return true;
         }
 
         // Ok, they couldn't move as a block, let's move them individually
         for (View v : mIntersectingViews) {
-            if (!addViewToTempLocation(v, mOccupiedRect, direction)) {
+            if (!addViewToTempLocation(v, mOccupiedRect, direction, solution)) {
                 return false;
             }
         }
@@ -1842,11 +1828,21 @@
         }
     }
 
+    private void copyOccupiedArray(boolean[][] occupied) {
+        for (int i = 0; i < mCountX; i++) {
+            for (int j = 0; j < mCountY; j++) {
+                occupied[i][j] = mOccupied[i][j];
+            }
+        }
+    }
+
     ItemConfiguration simpleSwap(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX,
             int spanY, int[] direction, View dragView, boolean decX, ItemConfiguration solution) {
-        // This creates a copy of the current occupied array, omitting the current view being
-        // dragged
-        resetTempLayoutToCurrent(dragView);
+        // Copy the current state into the solution. This solution will be manipulated as necessary.
+        copyCurrentStateToSolution(solution, false);
+        // Copy the current occupied array into the temporary occupied array. This array will be
+        // manipulated as necessary to find a solution.
+        copyOccupiedArray(mTmpOccupied);
 
         // We find the nearest cell into which we would place the dragged item, assuming there's
         // nothing in its way.
@@ -1856,7 +1852,8 @@
         boolean success = false;
         // First we try the exact nearest position of the item being dragged,
         // we will then want to try to move this around to other neighbouring positions
-        success = rearrangementExists(result[0], result[1], spanX, spanY, direction, dragView);
+        success = rearrangementExists(result[0], result[1], spanX, spanY, direction, dragView,
+                solution);
 
         if (!success) {
             // We try shrinking the widget down to size in an alternating pattern, shrink 1 in
@@ -1875,7 +1872,6 @@
             solution.dragViewY = result[1];
             solution.dragViewSpanX = spanX;
             solution.dragViewSpanY = spanY;
-            copyCurrentStateToSolution(solution, true);
         }
         return solution;
     }
@@ -1885,13 +1881,13 @@
         for (int i = 0; i < childCount; i++) {
             View child = mShortcutsAndWidgets.getChildAt(i);
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            Point p;
+            CellAndSpan c;
             if (temp) {
-                p = new Point(lp.tmpCellX, lp.tmpCellY);
+                c = new CellAndSpan(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan, lp.cellVSpan);
             } else {
-                p = new Point(lp.cellX, lp.cellY);
+                c = new CellAndSpan(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan);
             }
-            solution.map.put(child, p);
+            solution.map.put(child, c);
         }
     }
 
@@ -1907,12 +1903,13 @@
             View child = mShortcutsAndWidgets.getChildAt(i);
             if (child == dragView) continue;
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            Point p = solution.map.get(child);
-            if (p != null) {
-                lp.tmpCellX = p.x;
-                lp.tmpCellY = p.y;
-                markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan, lp.cellVSpan,
-                        mTmpOccupied, true);
+            CellAndSpan c = solution.map.get(child);
+            if (c != null) {
+                lp.tmpCellX = c.x;
+                lp.tmpCellY = c.y;
+                lp.cellHSpan = c.spanX;
+                lp.cellVSpan = c.spanY;
+                markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
             }
         }
         markCellsForView(solution.dragViewX, solution.dragViewY, solution.dragViewSpanX,
@@ -1933,13 +1930,11 @@
         for (int i = 0; i < childCount; i++) {
             View child = mShortcutsAndWidgets.getChildAt(i);
             if (child == dragView) continue;
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            Point p = solution.map.get(child);
-            if (p != null) {
-                if (lp.cellX != p.x || lp.cellY != p.y) {
-                    animateChildToPosition(child, p.x, p.y, 150, 0, DESTRUCTIVE_REORDER, false);
-                }
-                markCellsForView(p.x, p.y, lp.cellHSpan, lp.cellVSpan, occupied, true);
+            CellAndSpan c = solution.map.get(child);
+            if (c != null) {
+                animateChildToPosition(child, c.x, c.y, REORDER_ANIMATION_DURATION, 0,
+                        DESTRUCTIVE_REORDER, false);
+                markCellsForView(c.x, c.y, c.spanX, c.spanY, occupied, true);
             }
         }
         if (commitDragView) {
@@ -1948,6 +1943,128 @@
         }
     }
 
+    // This method starts or changes the reorder hint animations
+    private void beginOrAdjustHintAnimations(ItemConfiguration solution, View dragView, int delay) {
+        int childCount = mShortcutsAndWidgets.getChildCount();
+        int timeForPriorAnimationToComplete = getMaxCompletionTime();
+        for (int i = 0; i < childCount; i++) {
+            View child = mShortcutsAndWidgets.getChildAt(i);
+            if (child == dragView) continue;
+            CellAndSpan c = solution.map.get(child);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (c != null) {
+                ReorderHintAnimation rha = new ReorderHintAnimation(child, lp.cellX, lp.cellY,
+                        c.x, c.y, c.spanX, c.spanY);
+                rha.animate(timeForPriorAnimationToComplete);
+            }
+        }
+    }
+
+    // Class which represents the reorder hint animations. These animations show that an item is
+    // in a temporary state, and hint at where the item will return to.
+    class ReorderHintAnimation {
+        View child;
+        float deltaX;
+        float deltaY;
+        private static final int DURATION = 140;
+        private int repeatCount;
+        private boolean cancelOnCycleComplete = false;
+        ValueAnimator va;
+
+        public ReorderHintAnimation(View child, int cellX0, int cellY0, int cellX1, int cellY1,
+                int spanX, int spanY) {
+            regionToCenterPoint(cellX0, cellY0, spanX, spanY, mTmpPoint);
+            final int x0 = mTmpPoint[0];
+            final int y0 = mTmpPoint[1];
+            regionToCenterPoint(cellX1, cellY1, spanX, spanY, mTmpPoint);
+            final int x1 = mTmpPoint[0];
+            final int y1 = mTmpPoint[1];
+            final int dX = x1 - x0;
+            final int dY = y1 - y0;
+            deltaX = 0;
+            deltaY = 0;
+            if (dX == dY && dX == 0) {
+            } else {
+                if (dY == 0) {
+                    deltaX = mReorderHintAnimationMagnitude;
+                } else if (dX == 0) {
+                    deltaY = mReorderHintAnimationMagnitude;
+                } else {
+                    double angle = Math.atan( (float) (dY) / dX);
+                    deltaX = (int) (Math.cos(angle) * mReorderHintAnimationMagnitude);
+                    deltaY = (int) (Math.sin(angle) * mReorderHintAnimationMagnitude);
+                }
+            }
+            this.child = child;
+        }
+
+        void animate(int delay) {
+            if (mShakeAnimators.containsKey(child)) {
+                ReorderHintAnimation oldAnimation = mShakeAnimators.get(child);
+                oldAnimation.completeAnimation();
+                mShakeAnimators.remove(child);
+            }
+            if (deltaX == 0 && deltaY == 0) {
+                return;
+            }
+            va = ValueAnimator.ofFloat(0f, 1f);
+            va.setRepeatMode(ValueAnimator.REVERSE);
+            va.setRepeatCount(ValueAnimator.INFINITE);
+            va.setDuration(DURATION);
+            va.addUpdateListener(new AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    float r = ((Float) animation.getAnimatedValue()).floatValue();
+                    float x = r * deltaX;
+                    float y = r * deltaY;
+                    child.setTranslationX(x);
+                    child.setTranslationY(y);
+                }
+            });
+            va.addListener(new AnimatorListenerAdapter() {
+                public void onAnimationRepeat(Animator animation) {
+                    repeatCount++;
+                    // We make sure to end only after a full period
+                    if (cancelOnCycleComplete && repeatCount % 2 == 0) {
+                        va.cancel();
+                    }
+                }
+            });
+            va.setStartDelay(Math.max(REORDER_ANIMATION_DURATION, delay));
+            mShakeAnimators.put(child, this);
+            va.start();
+        }
+
+
+        private void completeAnimation() {
+            cancelOnCycleComplete = true;
+        }
+
+        // Returns the time required to complete the current oscillating animation
+        private int completionTime() {
+            if (repeatCount % 2 == 0) {
+                return (int) (va.getDuration() - va.getCurrentPlayTime() + DURATION);
+            } else {
+                return (int) (va.getDuration() - va.getCurrentPlayTime());
+            }
+        }
+    }
+
+    private void completeAndClearReorderHintAnimations() {
+        for (ReorderHintAnimation a: mShakeAnimators.values()) {
+            a.completeAnimation();
+        }
+        mShakeAnimators.clear();
+    }
+
+    private int getMaxCompletionTime() {
+        int maxTime = 0;
+        for (ReorderHintAnimation a: mShakeAnimators.values()) {
+            maxTime = Math.max(maxTime, a.completionTime());
+        }
+        return maxTime;
+    }
+
     private void commitTempPlacement() {
         for (int i = 0; i < mCountX; i++) {
             for (int j = 0; j < mCountY; j++) {
@@ -1956,10 +2073,17 @@
         }
         int childCount = mShortcutsAndWidgets.getChildCount();
         for (int i = 0; i < childCount; i++) {
-            LayoutParams lp = (LayoutParams) mShortcutsAndWidgets.getChildAt(i).getLayoutParams();
-            lp.cellX = lp.tmpCellX;
-            lp.cellY = lp.tmpCellY;
+            View child = mShortcutsAndWidgets.getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            ItemInfo info = (ItemInfo) child.getTag();
+            // We do a null check here because the item info can be null in the case of the
+            // AllApps button in the hotseat.
+            if (info != null) {
+                info.cellX = lp.cellX = lp.tmpCellX;
+                info.cellY = lp.cellY = lp.tmpCellY;
+            }
         }
+        mLauncher.getWorkspace().updateItemLocationsInDatabase(this);
     }
 
     public void setUseTempCoords(boolean useTempCoords) {
@@ -1970,22 +2094,6 @@
         }
     }
 
-    private void resetTempLayoutToCurrent(View ignoreView) {
-        for (int i = 0; i < mCountX; i++) {
-            for (int j = 0; j < mCountY; j++) {
-                mTmpOccupied[i][j] = mOccupied[i][j];
-            }
-        }
-        int childCount = mShortcutsAndWidgets.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = mShortcutsAndWidgets.getChildAt(i);
-            if (child == ignoreView) continue;
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            lp.tmpCellX = lp.cellX;
-            lp.tmpCellY = lp.cellY;
-        }
-    }
-
     ItemConfiguration findConfigurationNoShuffle(int pixelX, int pixelY, int minSpanX, int minSpanY,
             int spanX, int spanY, View dragView, ItemConfiguration solution) {
         int[] result = new int[2];
@@ -2009,9 +2117,103 @@
         markCellsAsUnoccupiedForView(child);
     }
 
+    /* This seems like it should be obvious and straight-forward, but when the direction vector
+    needs to match with the notion of the dragView pushing other views, we have to employ
+    a slightly more subtle notion of the direction vector. The question is what two points is
+    the vector between? The center of the dragView and its desired destination? Not quite, as
+    this doesn't necessarily coincide with the interaction of the dragView and items occupying
+    those cells. Instead we use some heuristics to often lock the vector to up, down, left
+    or right, which helps make pushing feel right.
+    */
+    private void getDirectionVectorForDrop(int dragViewCenterX, int dragViewCenterY, int spanX,
+            int spanY, View dragView, int[] resultDirection) {
+        int[] targetDestination = new int[2];
+
+        findNearestArea(dragViewCenterX, dragViewCenterY, spanX, spanY, targetDestination);
+        Rect dragRect = new Rect();
+        regionToRect(targetDestination[0], targetDestination[1], spanX, spanY, dragRect);
+        dragRect.offset(dragViewCenterX - dragRect.centerX(), dragViewCenterY - dragRect.centerY());
+
+        Rect dropRegionRect = new Rect();
+        getViewsIntersectingRegion(targetDestination[0], targetDestination[1], spanX, spanY,
+                dragView, dropRegionRect, mIntersectingViews);
+
+        int dropRegionSpanX = dropRegionRect.width();
+        int dropRegionSpanY = dropRegionRect.height();
+
+        regionToRect(dropRegionRect.left, dropRegionRect.top, dropRegionRect.width(),
+                dropRegionRect.height(), dropRegionRect);
+
+        int deltaX = (dropRegionRect.centerX() - dragViewCenterX) / spanX;
+        int deltaY = (dropRegionRect.centerY() - dragViewCenterY) / spanY;
+
+        if (dropRegionSpanX == mCountX || spanX == mCountX) {
+            deltaX = 0;
+        }
+        if (dropRegionSpanY == mCountY || spanY == mCountY) {
+            deltaY = 0;
+        }
+
+        if (deltaX == 0 && deltaY == 0) {
+            // No idea what to do, give a random direction.
+            resultDirection[0] = 1;
+            resultDirection[1] = 0;
+        } else {
+            computeDirectionVector(deltaX, deltaY, resultDirection);
+        }
+    }
+
+    // For a given cell and span, fetch the set of views intersecting the region.
+    private void getViewsIntersectingRegion(int cellX, int cellY, int spanX, int spanY,
+            View dragView, Rect boundingRect, ArrayList<View> intersectingViews) {
+        if (boundingRect != null) {
+            boundingRect.set(cellX, cellY, cellX + spanX, cellY + spanY);
+        }
+        intersectingViews.clear();
+        Rect r0 = new Rect(cellX, cellY, cellX + spanX, cellY + spanY);
+        Rect r1 = new Rect();
+        final int count = mShortcutsAndWidgets.getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = mShortcutsAndWidgets.getChildAt(i);
+            if (child == dragView) continue;
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            r1.set(lp.cellX, lp.cellY, lp.cellX + lp.cellHSpan, lp.cellY + lp.cellVSpan);
+            if (Rect.intersects(r0, r1)) {
+                mIntersectingViews.add(child);
+                if (boundingRect != null) {
+                    boundingRect.union(r1);
+                }
+            }
+        }
+    }
+
+    boolean isNearestDropLocationOccupied(int pixelX, int pixelY, int spanX, int spanY,
+            View dragView, int[] result) {
+        result = findNearestArea(pixelX, pixelY, spanX, spanY, result);
+        getViewsIntersectingRegion(result[0], result[1], spanX, spanY, dragView, null,
+                mIntersectingViews);
+        return !mIntersectingViews.isEmpty();
+    }
+
+    void revertTempState() {
+        if (!isItemPlacementDirty() || DESTRUCTIVE_REORDER) return;
+        final int count = mShortcutsAndWidgets.getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = mShortcutsAndWidgets.getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.cellY) {
+                lp.tmpCellX = lp.cellX;
+                lp.tmpCellY = lp.cellY;
+                animateChildToPosition(child, lp.cellX, lp.cellY, REORDER_ANIMATION_DURATION,
+                        0, false, false);
+            }
+        }
+        completeAndClearReorderHintAnimations();
+        setItemPlacementDirty(false);
+    }
+
     int[] createArea(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX, int spanY,
             View dragView, int[] result, int resultSpan[], int mode) {
-
         // First we determine if things have moved enough to cause a different layout
         result = findNearestArea(pixelX, pixelY, spanX, spanY, result);
 
@@ -2019,10 +2221,25 @@
             resultSpan = new int[2];
         }
 
-        // We attempt the first algorithm
-        regionToCenterPoint(result[0], result[1], spanX, spanY, mTmpPoint);
-        computeDirectionVector((mTmpPoint[0] - pixelX) / spanX, (mTmpPoint[1] - pixelY) / spanY,
-                mDirectionVector);
+        // When we are checking drop validity or actually dropping, we don't recompute the
+        // direction vector, since we want the solution to match the preview, and it's possible
+        // that the exact position of the item has changed to result in a new reordering outcome.
+        if ((mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL || mode == MODE_ACCEPT_DROP)
+               && mPreviousReorderDirection[0] != INVALID_DIRECTION) {
+            mDirectionVector[0] = mPreviousReorderDirection[0];
+            mDirectionVector[1] = mPreviousReorderDirection[1];
+            // We reset this vector after drop
+            if (mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL) {
+                mPreviousReorderDirection[0] = INVALID_DIRECTION;
+                mPreviousReorderDirection[1] = INVALID_DIRECTION;
+            }
+            
+        } else {
+            getDirectionVectorForDrop(pixelX, pixelY, spanX, spanY, dragView, mDirectionVector);
+            mPreviousReorderDirection[0] = mDirectionVector[0];
+            mPreviousReorderDirection[1] = mDirectionVector[1];
+        }
+
         ItemConfiguration swapSolution = simpleSwap(pixelX, pixelY, minSpanX, minSpanY,
                  spanX,  spanY, mDirectionVector, dragView,  true,  new ItemConfiguration());
 
@@ -2058,8 +2275,14 @@
                 setItemPlacementDirty(true);
                 animateItemsToSolution(finalSolution, dragView, mode == MODE_ON_DROP);
 
-                if (!DESTRUCTIVE_REORDER && mode == MODE_ON_DROP) {
+                if (!DESTRUCTIVE_REORDER &&
+                        (mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL)) {
                     commitTempPlacement();
+                    completeAndClearReorderHintAnimations();
+                    setItemPlacementDirty(false);
+                } else {
+                    beginOrAdjustHintAnimations(finalSolution, dragView,
+                            REORDER_ANIMATION_DURATION);
                 }
             }
         } else {
@@ -2070,31 +2293,37 @@
         if ((mode == MODE_ON_DROP || !foundSolution) && !DESTRUCTIVE_REORDER) {
             setUseTempCoords(false);
         }
-        boolean[][] occupied = mOccupied;
 
         mShortcutsAndWidgets.requestLayout();
         return result;
     }
 
-    public boolean isItemPlacementDirty() {
-        return mItemLocationsDirty;
+    void setItemPlacementDirty(boolean dirty) {
+        mItemPlacementDirty = dirty;
     }
-
-    public void setItemPlacementDirty(boolean dirty) {
-        mItemLocationsDirty = dirty;
+    boolean isItemPlacementDirty() {
+        return mItemPlacementDirty;
     }
 
     private class ItemConfiguration {
-        HashMap<View, Point> map = new HashMap<View, Point>();
+        HashMap<View, CellAndSpan> map = new HashMap<View, CellAndSpan>();
         boolean isSolution = false;
         int dragViewX, dragViewY, dragViewSpanX, dragViewSpanY;
 
         int area() {
             return dragViewSpanX * dragViewSpanY;
         }
-        void clear() {
-            map.clear();
-            isSolution = false;
+    }
+
+    private class CellAndSpan {
+        int x, y;
+        int spanX, spanY;
+
+        public CellAndSpan(int x, int y, int spanX, int spanY) {
+            this.x = x;
+            this.y = y;
+            this.spanX = spanX;
+            this.spanY = spanY;
         }
     }
 
@@ -2308,7 +2537,7 @@
         mDragCell[0] = mDragCell[1] = -1;
         mDragOutlineAnims[mDragOutlineCurrent].animateOut();
         mDragOutlineCurrent = (mDragOutlineCurrent + 1) % mDragOutlineAnims.length;
-
+        revertTempState();
         setIsDragOverlapping(false);
     }
 
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 6f45590..7e4225b 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -105,6 +105,15 @@
         return (d.dragSource instanceof Workspace) && (d.dragInfo instanceof FolderInfo);
     }
 
+    private void setHoverColor() {
+        mCurrentDrawable.startTransition(mTransitionDuration);
+        setTextColor(mHoverColor);
+    }
+    private void resetHoverColor() {
+        mCurrentDrawable.resetTransition();
+        setTextColor(mOriginalTextColor);
+    }
+
     @Override
     public boolean acceptDrop(DragObject d) {
         // We can remove everything including App shortcuts, folders, widgets, etc.
@@ -140,8 +149,7 @@
         mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
 
         mActive = isVisible;
-        mCurrentDrawable.resetTransition();
-        setTextColor(mOriginalTextColor);
+        resetHoverColor();
         ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
         if (getText().length() > 0) {
             setText(isUninstall ? R.string.delete_target_uninstall_label
@@ -158,16 +166,14 @@
     public void onDragEnter(DragObject d) {
         super.onDragEnter(d);
 
-        mCurrentDrawable.startTransition(mTransitionDuration);
-        setTextColor(mHoverColor);
+        setHoverColor();
     }
 
     public void onDragExit(DragObject d) {
         super.onDragExit(d);
 
         if (!d.dragComplete) {
-            mCurrentDrawable.resetTransition();
-            setTextColor(mOriginalTextColor);
+            resetHoverColor();
         } else {
             // Restore the hover color if we are deleting
             d.dragView.setColor(mHoverColor);
@@ -349,9 +355,15 @@
     }
 
     public void onFlingToDelete(final DragObject d, int x, int y, PointF vel) {
+        final boolean isAllApps = d.dragSource instanceof AppsCustomizePagedView;
+
         // Don't highlight the icon as it's animating
         d.dragView.setColor(0);
         d.dragView.updateInitialScaleToCurrentScale();
+        // Don't highlight the target if we are flinging from AllApps
+        if (isAllApps) {
+            resetHoverColor();
+        }
 
         if (mFlingDeleteMode == MODE_FLING_DELETE_TO_TRASH) {
             // Defer animating out the drop target if we are animating to it
@@ -396,8 +408,14 @@
             @Override
             public void run() {
                 mSearchDropTargetBar.onDragEnd();
-                mLauncher.exitSpringLoadedDragMode();
-                completeDrop(d);
+
+                // If we are dragging from AllApps, then we allow AppsCustomizePagedView to clean up
+                // itself, otherwise, complete the drop to initiate the deletion process
+                if (!isAllApps) {
+                    mLauncher.exitSpringLoadedDragMode();
+                    completeDrop(d);
+                }
+                mLauncher.getDragController().onDeferredEndFling(d);
             }
         };
         dragLayer.animateView(d.dragView, updateCb, duration, tInterpolator, onAnimationEndRunnable,
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 2a88925..eba89e5 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -366,7 +366,7 @@
             mDragObject.deferDragViewCleanupPostAnimation = false;
             mDragObject.cancelled = true;
             mDragObject.dragComplete = true;
-            mDragObject.dragSource.onDropCompleted(null, mDragObject, false);
+            mDragObject.dragSource.onDropCompleted(null, mDragObject, false, false);
         }
         endDrag();
     }
@@ -422,6 +422,10 @@
         }
     }
 
+    void onDeferredEndFling(DropTarget.DragObject d) {
+        d.dragSource.onFlingToDeleteCompleted();
+    }
+
     /**
      * Clamps the position to the drag layer bounds.
      */
@@ -648,7 +652,6 @@
 
         mDragObject.x = coordinates[0];
         mDragObject.y = coordinates[1];
-        mDragObject.dragComplete = true;
 
         // Clean up dragging on the target if it's not the current fling delete target otherwise,
         // start dragging to it.
@@ -659,13 +662,16 @@
         // Drop onto the fling-to-delete target
         boolean accepted = false;
         mFlingToDeleteDropTarget.onDragEnter(mDragObject);
+        // We must set dragComplete to true _only_ after we "enter" the fling-to-delete target for
+        // "drop"
+        mDragObject.dragComplete = true;
         mFlingToDeleteDropTarget.onDragExit(mDragObject);
         if (mFlingToDeleteDropTarget.acceptDrop(mDragObject)) {
             mFlingToDeleteDropTarget.onFlingToDelete(mDragObject, mDragObject.x, mDragObject.y,
                     vel);
             accepted = true;
         }
-        mDragObject.dragSource.onDropCompleted((View) mFlingToDeleteDropTarget, mDragObject,
+        mDragObject.dragSource.onDropCompleted((View) mFlingToDeleteDropTarget, mDragObject, true,
                 accepted);
     }
 
@@ -684,7 +690,7 @@
                 accepted = true;
             }
         }
-        mDragObject.dragSource.onDropCompleted((View) dropTarget, mDragObject, accepted);
+        mDragObject.dragSource.onDropCompleted((View) dropTarget, mDragObject, false, accepted);
     }
 
     private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java
index a654b93..5440477 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -25,6 +25,21 @@
  *
  */
 public interface DragSource {
+    /**
+     * @return whether items dragged from this source supports
+     */
     boolean supportsFlingToDelete();
-    void onDropCompleted(View target, DragObject d, boolean success);
+
+    /**
+     * A callback specifically made back to the source after an item from this source has been flung
+     * to be deleted on a DropTarget.  In such a situation, this method will be called after
+     * onDropCompleted, and more importantly, after the fling animation has completed.
+     */
+    void onFlingToDeleteCompleted();
+
+    /**
+     * A callback made back to the source after an item from this source has been dropped on a
+     * DropTarget.
+     */
+    void onDropCompleted(View target, DragObject d, boolean isFlingToDelete, boolean success);
 }
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 6856a09..c502fb7 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -44,6 +44,7 @@
 import android.widget.TextView;
 
 import com.android.launcher.R;
+import com.android.launcher2.DropTarget.DragObject;
 import com.android.launcher2.FolderInfo.FolderListener;
 
 import java.util.ArrayList;
@@ -619,7 +620,8 @@
         mReorderAlarm.cancelAlarm();
     }
 
-    public void onDropCompleted(View target, DragObject d, boolean success) {
+    public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
+            boolean success) {
         if (success) {
             if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon) {
                 replaceFolderWithFinalItem();
@@ -653,10 +655,20 @@
         updateItemLocationsInDatabase();
     }
 
+    @Override
     public boolean supportsFlingToDelete() {
         return true;
     }
 
+    public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+        // Do nothing
+    }
+
+    @Override
+    public void onFlingToDeleteCompleted() {
+        // Do nothing
+    }
+
     private void updateItemLocationsInDatabase() {
         ArrayList<View> list = getItemsInReadingOrder();
         for (int i = 0; i < list.size(); i++) {
@@ -928,10 +940,6 @@
         mInfo.add(item);
     }
 
-    public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
-        // Do nothing
-    }
-
     public void onAdd(ShortcutInfo item) {
         mItemsInvalidated = true;
         // If the item was dropped onto this open folder, we have done the work associated
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index e04ce64..4c0974f 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -17,9 +17,9 @@
 package com.android.launcher2;
 
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.widget.Toast;
@@ -27,10 +27,21 @@
 import com.android.launcher.R;
 
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
 
 public class InstallShortcutReceiver extends BroadcastReceiver {
     public static final String ACTION_INSTALL_SHORTCUT =
             "com.android.launcher.action.INSTALL_SHORTCUT";
+    public static final String NEW_APPS_PAGE_KEY = "apps.new.page";
+    public static final String NEW_APPS_LIST_KEY = "apps.new.list";
+
+    public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
+    public static final int NEW_SHORTCUT_STAGGER_DELAY = 75;
+
+    private static final int INSTALL_SHORTCUT_SUCCESSFUL = 0;
+    private static final int INSTALL_SHORTCUT_IS_DUPLICATE = -1;
+    private static final int INSTALL_SHORTCUT_NO_SPACE = -2;
 
     // A mime-type representing shortcut data
     public static final String SHORTCUT_MIMETYPE =
@@ -42,6 +53,8 @@
         if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
             return;
         }
+        String spKey = LauncherApplication.getSharedPreferencesKey();
+        SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
 
         final int screen = Launcher.getScreen();
         final Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
@@ -62,26 +75,35 @@
         }
 
         final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
-        final boolean shortcutExists = LauncherModel.shortcutExists(context, name, intent);
-        final String[] errorMsgs = {""};
+        final boolean exists = LauncherModel.shortcutExists(context, name, intent);
+        final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL};
 
-        if (!installShortcut(context, data, items, name, intent, screen, shortcutExists,
-                errorMsgs)) {
-            // The target screen is full, let's try the other screens
-            for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
-                if (i != screen && installShortcut(context, data, items, name, intent, i,
-                        shortcutExists, errorMsgs)) break;
+        // Try adding the target to the workspace screens incrementally, starting at the current
+        // screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
+        boolean found = false;
+        for (int i = 0; i < (2 * Launcher.SCREEN_COUNT) + 1 && !found; ++i) {
+            int si = screen + (int) ((i / 2f) + 0.5f) * ((i % 2 == 1) ? 1 : -1);
+            if (0 <= si && si < Launcher.SCREEN_COUNT) {
+                found = installShortcut(context, data, items, name, intent, si, exists, sp, result);
             }
         }
 
-        if (!errorMsgs[0].isEmpty()) {
-            Toast.makeText(context, errorMsgs[0],
-                    Toast.LENGTH_SHORT).show();
+        // We only report error messages (duplicate shortcut or out of space) as the add-animation
+        // will provide feedback otherwise
+        if (!found) {
+            if (result[0] == INSTALL_SHORTCUT_NO_SPACE) {
+                Toast.makeText(context, context.getString(R.string.out_of_space),
+                        Toast.LENGTH_SHORT).show();
+            } else if (result[0] == INSTALL_SHORTCUT_IS_DUPLICATE) {
+                Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name),
+                        Toast.LENGTH_SHORT).show();
+            }
         }
     }
 
     private boolean installShortcut(Context context, Intent data, ArrayList<ItemInfo> items,
-            String name, Intent intent, int screen, boolean shortcutExists, String[] errorMsgs) {
+            String name, Intent intent, int screen, boolean shortcutExists,
+            SharedPreferences sharedPrefs, int[] result) {
         if (findEmptyCell(context, items, mCoordinates, screen)) {
             if (intent != null) {
                 if (intent.getAction() == null) {
@@ -92,23 +114,35 @@
                 // different places)
                 boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
                 if (duplicate || !shortcutExists) {
+                    // If the new app is going to fall into the same page as before, then just
+                    // continue adding to the current page
+                    int newAppsScreen = sharedPrefs.getInt(NEW_APPS_PAGE_KEY, screen);
+                    Set<String> newApps = new HashSet<String>();
+                    if (newAppsScreen == screen) {
+                        newApps = sharedPrefs.getStringSet(NEW_APPS_LIST_KEY, newApps);
+                    }
+                    newApps.add(intent.toUri(0).toString());
+                    sharedPrefs.edit()
+                               .putInt(NEW_APPS_PAGE_KEY, screen)
+                               .putStringSet(NEW_APPS_LIST_KEY, newApps)
+                               .commit();
+
+                    // Update the Launcher db
                     LauncherApplication app = (LauncherApplication) context.getApplicationContext();
                     ShortcutInfo info = app.getModel().addShortcut(context, data,
-                            LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0],
-                            mCoordinates[1], true);
-                    if (info != null) {
-                        errorMsgs[0] = context.getString(R.string.shortcut_installed, name);
-                    } else {
+                            LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
+                            mCoordinates[0], mCoordinates[1], true);
+                    if (info == null) {
                         return false;
                     }
                 } else {
-                    errorMsgs[0] = context.getString(R.string.shortcut_duplicate, name);
+                    result[0] = INSTALL_SHORTCUT_IS_DUPLICATE;
                 }
 
                 return true;
             }
         } else {
-            errorMsgs[0] = context.getString(R.string.out_of_space);
+            result[0] = INSTALL_SHORTCUT_NO_SPACE;
         }
 
         return false;
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 0c1b76f..ee540f8 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -55,6 +55,7 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
@@ -84,6 +85,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.AccelerateInterpolator;
+import android.view.animation.BounceInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Advanceable;
@@ -103,7 +105,12 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Default launcher application.
@@ -253,6 +260,10 @@
     // it from the context.
     private SharedPreferences mSharedPrefs;
 
+    // Holds the page that we need to animate to, and the icon views that we need to animate up
+    // when we scroll to that page on resume.
+    private int mNewShortcutAnimatePage = -1;
+    private ArrayList<View> mNewShortcutAnimateViews = new ArrayList<View>();
 
     private BubbleTextView mWaitingForResume;
 
@@ -280,7 +291,8 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         LauncherApplication app = ((LauncherApplication)getApplication());
-        mSharedPrefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
+        mSharedPrefs = getSharedPreferences(LauncherApplication.getSharedPreferencesKey(),
+                Context.MODE_PRIVATE);
         mModel = app.setLauncher(this);
         mIconCache = app.getIconCache();
         mDragController = new DragController(this);
@@ -317,7 +329,7 @@
         }
 
         if (!mRestoring) {
-            mModel.startLoader(this, true);
+            mModel.startLoader(true);
         }
 
         if (!mModel.isAllAppsLoaded()) {
@@ -593,10 +605,11 @@
     @Override
     protected void onResume() {
         super.onResume();
+
         mPaused = false;
         if (mRestoring || mOnResumeNeedsLoad) {
             mWorkspaceLoading = true;
-            mModel.startLoader(this, true);
+            mModel.startLoader(true);
             mRestoring = false;
             mOnResumeNeedsLoad = false;
         }
@@ -725,7 +738,7 @@
             showAllApps(false);
         }
 
-        final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
+        int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
         if (currentScreen > -1) {
             mWorkspace.setCurrentPage(currentScreen);
         }
@@ -868,7 +881,7 @@
             cellXY[0] = cellX;
             cellXY[1] = cellY;
         } else if (!layout.findCellForSpan(cellXY, 1, 1)) {
-            showOutOfSpaceMessage();
+            showOutOfSpaceMessage(isHotseatLayout(layout));
             return;
         }
 
@@ -931,7 +944,7 @@
         }
 
         if (!foundCellSpan) {
-            showOutOfSpaceMessage();
+            showOutOfSpaceMessage(isHotseatLayout(layout));
             return;
         }
 
@@ -1026,7 +1039,7 @@
                     }
                 }.start();
             }
-            showOutOfSpaceMessage();
+            showOutOfSpaceMessage(isHotseatLayout(layout));
             return;
         }
 
@@ -1212,8 +1225,9 @@
         launcherInfo.hostView = null;
     }
 
-    void showOutOfSpaceMessage() {
-        Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+    void showOutOfSpaceMessage(boolean isHotseatLayout) {
+        int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);
+        Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();
     }
 
     public LauncherAppWidgetHost getAppWidgetHost() {
@@ -1828,6 +1842,8 @@
     public void onClickAppMarketButton(View v) {
         if (mAppMarketIntent != null) {
             startActivitySafely(mAppMarketIntent, "app market");
+        } else {
+            Log.e(TAG, "Invalid app market intent.");
         }
     }
 
@@ -2184,7 +2200,7 @@
 
                 if (mWorkspaceLoading) {
                     lockAllApps();
-                    mModel.startLoader(Launcher.this, false);
+                    mModel.startLoader(false);
                 } else {
                     final FolderIcon folderIcon = (FolderIcon)
                             mWorkspace.getViewForTag(mFolderInfo);
@@ -2196,7 +2212,7 @@
                     } else {
                         lockAllApps();
                         mWorkspaceLoading = true;
-                        mModel.startLoader(Launcher.this, false);
+                        mModel.startLoader(false);
                     }
                 }
             }
@@ -2738,7 +2754,7 @@
      */
     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
-            showOutOfSpaceMessage();
+            showOutOfSpaceMessage(isHotseatLayout(layout));
         }
     }
 
@@ -3076,7 +3092,6 @@
         }
     }
 
-
     /**
      * Refreshes the shortcuts shown on the workspace.
      *
@@ -3085,6 +3100,8 @@
     public void startBinding() {
         final Workspace workspace = mWorkspace;
 
+        mNewShortcutAnimatePage = -1;
+        mNewShortcutAnimateViews.clear();
         mWorkspace.clearDropTargets();
         int count = workspace.getChildCount();
         for (int i = 0; i < count; i++) {
@@ -3106,8 +3123,12 @@
     public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) {
         setLoadOnResume();
 
-        final Workspace workspace = mWorkspace;
-        for (int i=start; i<end; i++) {
+        // Get the list of added shortcuts and intersect them with the set of shortcuts here
+        Set<String> newApps = new HashSet<String>();
+        newApps = mSharedPrefs.getStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, newApps);
+
+        Workspace workspace = mWorkspace;
+        for (int i = start; i < end; i++) {
             final ItemInfo item = shortcuts.get(i);
 
             // Short circuit if we are loading dock items for a configuration which has no dock
@@ -3119,9 +3140,23 @@
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
-                    View shortcut = createShortcut((ShortcutInfo)item);
+                    ShortcutInfo info = (ShortcutInfo) item;
+                    String uri = info.intent.toUri(0).toString();
+                    View shortcut = createShortcut(info);
                     workspace.addInScreen(shortcut, item.container, item.screen, item.cellX,
                             item.cellY, 1, 1, false);
+                    if (newApps.contains(uri)) {
+                        newApps.remove(uri);
+
+                        // Prepare the view to be animated up
+                        shortcut.setAlpha(0f);
+                        shortcut.setScaleX(0f);
+                        shortcut.setScaleY(0f);
+                        mNewShortcutAnimatePage = item.screen;
+                        if (!mNewShortcutAnimateViews.contains(shortcut)) {
+                            mNewShortcutAnimateViews.add(shortcut);
+                        }
+                    }
                     break;
                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
@@ -3132,6 +3167,7 @@
                     break;
             }
         }
+
         workspace.requestLayout();
     }
 
@@ -3169,11 +3205,6 @@
         item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
         item.hostView.setTag(item);
 
-        // We need to load the minimum span and embed it into the item info
-        int[] minSpan = getMinSpanForWidget(appWidgetInfo, null);
-        item.minSpanX = minSpan[0];
-        item.minSpanY = minSpan[1];
-
         workspace.addInScreen(item.hostView, item.container, item.screen, item.cellX,
                 item.cellY, item.spanX, item.spanY, false);
 
@@ -3207,8 +3238,6 @@
             mSavedInstanceState = null;
         }
 
-        mWorkspaceLoading = false;
-
         // If we received the result of any pending adds while the loader was running (e.g. the
         // widget configuration forced an orientation change), process them now.
         for (int i = 0; i < sPendingAddList.size(); i++) {
@@ -3220,7 +3249,72 @@
         // package changes in bindSearchablesChanged()
         updateAppMarketIcon();
 
-        mWorkspace.postDelayed(mBuildLayersRunnable, 500);
+        // Animate up any icons as necessary
+        if (mVisible || mWorkspaceLoading) {
+            Runnable newAppsRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    runNewAppsAnimation();
+                }
+            };
+            if (mNewShortcutAnimatePage > -1 &&
+                    mNewShortcutAnimatePage != mWorkspace.getCurrentPage()) {
+                mWorkspace.snapToPage(mNewShortcutAnimatePage, newAppsRunnable);
+            } else {
+                newAppsRunnable.run();
+            }
+        }
+
+        mWorkspaceLoading = false;
+    }
+
+    /**
+     * Runs a new animation that scales up icons that were added while Launcher was in the
+     * background.
+     */
+    private void runNewAppsAnimation() {
+        AnimatorSet anim = new AnimatorSet();
+        Collection<Animator> bounceAnims = new ArrayList<Animator>();
+        Collections.sort(mNewShortcutAnimateViews, new Comparator<View>() {
+            @Override
+            public int compare(View a, View b) {
+                CellLayout.LayoutParams alp = (CellLayout.LayoutParams) a.getLayoutParams();
+                CellLayout.LayoutParams blp = (CellLayout.LayoutParams) b.getLayoutParams();
+                int cellCountX = LauncherModel.getCellCountX();
+                return (alp.cellY * cellCountX + alp.cellX) - (blp.cellY * cellCountX + blp.cellX);
+            }
+        });
+        for (int i = 0; i < mNewShortcutAnimateViews.size(); ++i) {
+            View v = mNewShortcutAnimateViews.get(i);
+            ValueAnimator bounceAnim = ObjectAnimator.ofPropertyValuesHolder(v,
+                    PropertyValuesHolder.ofFloat("alpha", 1f),
+                    PropertyValuesHolder.ofFloat("scaleX", 1f),
+                    PropertyValuesHolder.ofFloat("scaleY", 1f));
+            bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);
+            bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);
+            bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());
+            bounceAnims.add(bounceAnim);
+        }
+        anim.playTogether(bounceAnims);
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mWorkspace.postDelayed(mBuildLayersRunnable, 500);
+            }
+        });
+        anim.start();
+
+        // Clean up
+        mNewShortcutAnimatePage = -1;
+        mNewShortcutAnimateViews.clear();
+        new Thread("clearNewAppsThread") {
+            public void run() {
+                mSharedPrefs.edit()
+                            .putInt(InstallShortcutReceiver.NEW_APPS_PAGE_KEY, -1)
+                            .putStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, null)
+                            .commit();
+            }
+        }.start();
     }
 
     @Override
@@ -3363,7 +3457,6 @@
     }
 
     /* Cling related */
-    private static final String PREFS_KEY = "com.android.launcher2.prefs";
     private boolean isClingsEnabled() {
         // disable clings when running in a test harness
         if(ActivityManager.isRunningInTestHarness()) return false;
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index 47ce0b7..ef1eb5f 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -37,6 +37,7 @@
     private static boolean sIsScreenLarge;
     private static float sScreenDensity;
     private static int sLongPressTimeout = 300;
+    private static final String sSharedPreferencesKey = "com.android.launcher2.prefs";
     WeakReference<LauncherProvider> mLauncherProvider;
 
     @Override
@@ -94,7 +95,10 @@
     private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {
         @Override
         public void onChange(boolean selfChange) {
-            mModel.startLoader(LauncherApplication.this, false);
+            // If the database has ever changed, then we really need to force a reload of the
+            // workspace on the next load
+            mModel.resetLoadedState(false, true);
+            mModel.startLoaderFromBackground();
         }
     };
 
@@ -119,6 +123,10 @@
         return mLauncherProvider.get();
     }
 
+    public static String getSharedPreferencesKey() {
+        return sSharedPreferencesKey;
+    }
+
     public static boolean isScreenLarge() {
         return sIsScreenLarge;
     }
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 159ddb0..30eb86c 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -649,19 +649,24 @@
     }
 
     private void forceReload() {
-        synchronized (mLock) {
-            // Stop any existing loaders first, so they don't set mAllAppsLoaded or
-            // mWorkspaceLoaded to true later
-            stopLoaderLocked();
-            mAllAppsLoaded = false;
-            mWorkspaceLoaded = false;
-        }
+        resetLoadedState(true, true);
+
         // Do this here because if the launcher activity is running it will be restarted.
         // If it's not running startLoaderFromBackground will merely tell it that it needs
         // to reload.
         startLoaderFromBackground();
     }
 
+    public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) {
+        synchronized (mLock) {
+            // Stop any existing loaders first, so they don't set mAllAppsLoaded or
+            // mWorkspaceLoaded to true later
+            stopLoaderLocked();
+            if (resetAllAppsLoaded) mAllAppsLoaded = false;
+            if (resetWorkspaceLoaded) mWorkspaceLoaded = false;
+        }
+    }
+
     /**
      * When the launcher is in the background, it's possible for it to miss paired
      * configuration changes.  So whenever we trigger the loader from the background
@@ -680,7 +685,7 @@
             }
         }
         if (runLoader) {
-            startLoader(mApp, false);
+            startLoader(false);
         }
     }
 
@@ -698,7 +703,7 @@
         return isLaunching;
     }
 
-    public void startLoader(Context context, boolean isLaunching) {
+    public void startLoader(boolean isLaunching) {
         synchronized (mLock) {
             if (DEBUG_LOADERS) {
                 Log.d(TAG, "startLoader isLaunching=" + isLaunching);
@@ -709,7 +714,7 @@
                 // If there is already one running, tell it to stop.
                 // also, don't downgrade isLaunching if we're already running
                 isLaunching = isLaunching || stopLoaderLocked();
-                mLoaderTask = new LoaderTask(context, isLaunching);
+                mLoaderTask = new LoaderTask(mApp, isLaunching);
                 sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                 sWorker.post(mLoaderTask);
             }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 0854508..5434704 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -62,7 +62,8 @@
     // the min drag distance for a fling to register, to prevent random page shifts
     private static final int MIN_LENGTH_FOR_FLING = 25;
 
-    private static final int PAGE_SNAP_ANIMATION_DURATION = 550;
+    protected static final int PAGE_SNAP_ANIMATION_DURATION = 550;
+    protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
     protected static final float NANOTIME_DIV = 1000000000.0f;
 
     private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
diff --git a/src/com/android/launcher2/SmoothPagedView.java b/src/com/android/launcher2/SmoothPagedView.java
index fe763f5..e6414d9 100644
--- a/src/com/android/launcher2/SmoothPagedView.java
+++ b/src/com/android/launcher2/SmoothPagedView.java
@@ -35,11 +35,11 @@
 
     private Interpolator mScrollInterpolator;
 
-    private static class WorkspaceOvershootInterpolator implements Interpolator {
+    public static class OvershootInterpolator implements Interpolator {
         private static final float DEFAULT_TENSION = 1.3f;
         private float mTension;
 
-        public WorkspaceOvershootInterpolator() {
+        public OvershootInterpolator() {
             mTension = DEFAULT_TENSION;
         }
 
@@ -101,7 +101,7 @@
         if (mScrollMode == DEFAULT_MODE) {
             mBaseLineFlingVelocity = 2500.0f;
             mFlingVelocityInfluence = 0.4f;
-            mScrollInterpolator = new WorkspaceOvershootInterpolator();
+            mScrollInterpolator = new OvershootInterpolator();
             mScroller = new Scroller(getContext(), mScrollInterpolator);
         }
     }
@@ -139,9 +139,9 @@
         }
 
         if (settle) {
-            ((WorkspaceOvershootInterpolator) mScrollInterpolator).setDistance(screenDelta);
+            ((OvershootInterpolator) mScrollInterpolator).setDistance(screenDelta);
         } else {
-            ((WorkspaceOvershootInterpolator) mScrollInterpolator).disableSettle();
+            ((OvershootInterpolator) mScrollInterpolator).disableSettle();
         }
 
         velocity = Math.abs(velocity);
diff --git a/src/com/android/launcher2/WallpaperChooserDialogFragment.java b/src/com/android/launcher2/WallpaperChooserDialogFragment.java
index 030d33d..eec699e 100644
--- a/src/com/android/launcher2/WallpaperChooserDialogFragment.java
+++ b/src/com/android/launcher2/WallpaperChooserDialogFragment.java
@@ -82,10 +82,7 @@
         outState.putBoolean(EMBEDDED_KEY, mEmbedded);
     }
 
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-
+    private void cancelLoader() {
         if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
             mLoader.cancel(true);
             mLoader = null;
@@ -93,6 +90,20 @@
     }
 
     @Override
+    public void onDetach() {
+        super.onDetach();
+
+        cancelLoader();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        cancelLoader();
+    }
+
+    @Override
     public void onDismiss(DialogInterface dialog) {
         super.onDismiss(dialog);
         /* On orientation changes, the dialog is effectively "dismissed" so this is called
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 12c8d8a..06e0185 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -59,6 +59,7 @@
 import android.widget.TextView;
 
 import com.android.launcher.R;
+import com.android.launcher2.DropTarget.DragObject;
 import com.android.launcher2.FolderIcon.FolderRingAnimator;
 import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 import com.android.launcher2.LauncherSettings.Favorites;
@@ -183,6 +184,7 @@
     WallpaperOffsetInterpolator mWallpaperOffset;
     boolean mUpdateWallpaperOffsetImmediately = false;
     private Runnable mDelayedResizeRunnable;
+    private Runnable mDelayedSnapToPageRunnable;
     private int mDisplayWidth;
     private int mDisplayHeight;
     private boolean mIsStaticWallpaper;
@@ -196,6 +198,7 @@
     private FolderRingAnimator mDragFolderRingAnimator = null;
     private View mLastDragOverView = null;
     private boolean mCreateUserFolderOnDrop = false;
+    private boolean mWillAddToExistingFolder = false;
 
     // Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
     private float mXDown;
@@ -373,32 +376,12 @@
         mIsDragOccuring = true;
         updateChildrenLayersEnabled();
         mLauncher.lockScreenOrientationOnLargeUI();
-
-        // Fade out the workspace slightly to highlight the currently dragging item
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            CellLayout cl = (CellLayout) getPageAt(i);
-            cl.getShortcutsAndWidgets().animate().alpha(mDragFadeOutAlpha)
-                .setInterpolator(new AccelerateInterpolator(1.5f))
-                .setDuration(mDragFadeOutDuration)
-                .start();
-        }
     }
 
     public void onDragEnd() {
         mIsDragOccuring = false;
         updateChildrenLayersEnabled();
         mLauncher.unlockScreenOrientationOnLargeUI();
-
-        // Fade the workspace back in after we have completed dragging
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            CellLayout cl = (CellLayout) getPageAt(i);
-            cl.getShortcutsAndWidgets().animate().alpha(1f)
-                .setInterpolator(new DecelerateInterpolator(1.5f))
-                .setDuration(mDragFadeOutDuration)
-                .start();
-        }
     }
 
     /**
@@ -427,7 +410,7 @@
         mWallpaperTravelWidth = (int) (mDisplayWidth *
                 wallpaperTravelToScreenWidthRatio(mDisplayWidth, mDisplayHeight));
 
-        mMaxDistanceForFolderCreation = (0.5f * res.getDimension(R.dimen.app_icon_size));
+        mMaxDistanceForFolderCreation = (0.5f * res.getDimensionPixelSize(R.dimen.app_icon_size));
         mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
     }
 
@@ -694,7 +677,7 @@
 
     @Override
     protected boolean isScrollingIndicatorEnabled() {
-        return mState != State.SPRING_LOADED;
+        return super.isScrollingIndicatorEnabled() && (mState != State.SPRING_LOADED);
     }
 
     protected void onPageBeginMoving() {
@@ -765,6 +748,11 @@
             mDelayedResizeRunnable.run();
             mDelayedResizeRunnable = null;
         }
+
+        if (mDelayedSnapToPageRunnable != null) {
+            mDelayedSnapToPageRunnable.run();
+            mDelayedSnapToPageRunnable = null;
+        }
     }
 
     @Override
@@ -906,6 +894,20 @@
         computeWallpaperScrollRatio(whichPage);
     }
 
+    @Override
+    protected void snapToPage(int whichPage, int duration) {
+        super.snapToPage(whichPage, duration);
+        computeWallpaperScrollRatio(whichPage);
+    }
+
+    protected void snapToPage(int whichPage, Runnable r) {
+        if (mDelayedSnapToPageRunnable != null) {
+            mDelayedSnapToPageRunnable.run();
+        }
+        mDelayedSnapToPageRunnable = r;
+        snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION);
+    }
+
     private void computeWallpaperScrollRatio(int page) {
         // Here, we determine what the desired scroll would be with and without a layout scale,
         // and compute a ratio between the two. This allows us to adjust the wallpaper offset
@@ -1403,9 +1405,8 @@
     }
 
     private void updateChildrenLayersEnabled() {
-        boolean small = isSmall() || mIsSwitchingState;
-        boolean dragging = mAnimatingViewIntoPlace || mIsDragOccuring;
-        boolean enableChildrenLayers = small || dragging || isPageMoving();
+        boolean small = mState == State.SMALL || mIsSwitchingState;
+        boolean enableChildrenLayers = small || mAnimatingViewIntoPlace || isPageMoving();
 
         if (enableChildrenLayers != mChildrenLayersEnabled) {
             mChildrenLayersEnabled = enableChildrenLayers;
@@ -1686,9 +1687,9 @@
                         .setInterpolator(mZoomInInterpolator);
                     anim.play(a);
 
-                    LauncherViewPropertyAnimator alphaAnim =
-                        new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
                     if (mOldAlphas[i] != mNewAlphas[i]) {
+                        LauncherViewPropertyAnimator alphaAnim =
+                            new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
                         alphaAnim.alpha(mNewAlphas[i])
                             .setDuration(duration)
                             .setInterpolator(mZoomInInterpolator);
@@ -2001,12 +2002,10 @@
 
             int spanX = 1;
             int spanY = 1;
-            View ignoreView = null;
             if (mDragInfo != null) {
                 final CellLayout.CellInfo dragCellInfo = mDragInfo;
                 spanX = dragCellInfo.spanX;
                 spanY = dragCellInfo.spanY;
-                ignoreView = dragCellInfo.cell;
             } else {
                 final ItemInfo dragInfo = (ItemInfo) d.dragInfo;
                 spanX = dragInfo.spanX;
@@ -2044,7 +2043,8 @@
             if (!foundCell) {
                 // Don't show the message if we are dropping on the AllApps button and the hotseat
                 // is full
-                if (mTargetCell != null && mLauncher.isHotseatLayout(mDragTargetLayout)) {
+                boolean isHotseat = mLauncher.isHotseatLayout(mDragTargetLayout);
+                if (mTargetCell != null && isHotseat) {
                     Hotseat hotseat = mLauncher.getHotseat();
                     if (hotseat.isAllAppsButtonRank(
                             hotseat.getOrderInHotseat(mTargetCell[0], mTargetCell[1]))) {
@@ -2052,7 +2052,7 @@
                     }
                 }
 
-                mLauncher.showOutOfSpaceMessage();
+                mLauncher.showOutOfSpaceMessage(isHotseat);
                 return false;
             }
         }
@@ -2062,9 +2062,15 @@
     boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell, float
             distance, boolean considerTimeout) {
         if (distance > mMaxDistanceForFolderCreation) return false;
-
         View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
 
+        if (dropOverView != null) {
+            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) dropOverView.getLayoutParams();
+            if (lp.useTmpCoords && (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.tmpCellY)) {
+                return false;
+            }
+        }
+
         boolean hasntMoved = false;
         if (mDragInfo != null) {
             hasntMoved = dropOverView == mDragInfo.cell;
@@ -2085,8 +2091,15 @@
     boolean willAddToExistingUserFolder(Object dragInfo, CellLayout target, int[] targetCell,
             float distance) {
         if (distance > mMaxDistanceForFolderCreation) return false;
-
         View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+
+        if (dropOverView != null) {
+            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) dropOverView.getLayoutParams();
+            if (lp.useTmpCoords && (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.tmpCellY)) {
+                return false;
+            }
+        }
+
         if (dropOverView instanceof FolderIcon) {
             FolderIcon fi = (FolderIcon) dropOverView;
             if (fi.acceptDrop(dragInfo)) {
@@ -2101,6 +2114,7 @@
             Runnable postAnimationRunnable) {
         if (distance > mMaxDistanceForFolderCreation) return false;
         View v = target.getChildAt(targetCell[0], targetCell[1]);
+
         boolean hasntMoved = false;
         if (mDragInfo != null) {
             CellLayout cellParent = getParentCellLayoutForView(mDragInfo.cell);
@@ -2153,6 +2167,9 @@
         if (distance > mMaxDistanceForFolderCreation) return false;
 
         View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+        if (!mWillAddToExistingFolder) return false;
+        mWillAddToExistingFolder = false;
+
         if (dropOverView instanceof FolderIcon) {
             FolderIcon fi = (FolderIcon) dropOverView;
             if (fi.acceptDrop(d.dragInfo)) {
@@ -2262,10 +2279,11 @@
 
                     // update the item's position after drop
                     CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
-                    lp.cellX = mTargetCell[0];
-                    lp.cellY = mTargetCell[1];
+                    lp.cellX = lp.tmpCellX = mTargetCell[0];
+                    lp.cellY = lp.tmpCellY = mTargetCell[1];
                     lp.cellHSpan = item.spanX;
                     lp.cellVSpan = item.spanY;
+                    lp.isLockedToGrid = true;
                     cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screen,
                             mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
 
@@ -2341,10 +2359,6 @@
         }
     }
 
-    public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
-        // Do nothing
-    }
-
     public void setFinalScrollForPageChange(int screen) {
         if (screen >= 0) {
             mSavedScrollX = getScrollX();
@@ -2765,8 +2779,31 @@
                 minSpanY = item.minSpanY;
             }
 
-            if (!folder && !mReorderAlarm.alarmPending() && (mLastReorderX != mTargetCell[0] ||
-                    mLastReorderY != mTargetCell[1])) {
+            int[] reorderPosition = new int[2];
+            reorderPosition = findNearestArea((int) mDragViewVisualCenter[0],
+                    (int) mDragViewVisualCenter[1], item.spanX, item.spanY, mDragTargetLayout,
+                    reorderPosition);
+
+            if (!mDragTargetLayout.isNearestDropLocationOccupied((int) mDragViewVisualCenter[0],
+                    (int) mDragViewVisualCenter[1], item.spanX, item.spanY, child, mTargetCell)) {
+                // If the current hover area isn't occupied (permanently) by any items, then we
+                // reset all the reordering.
+                mDragTargetLayout.revertTempState();
+                mDragMode = DRAG_MODE_NONE;
+                mLastDragOverView = dragOverView;
+                if (mReorderAlarm != null) {
+                    mReorderAlarm.cancelAlarm();
+                }
+                mLastReorderX = -1;
+                mLastReorderY = -1;
+                mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
+                        (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
+                        mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false,
+                        d.dragView.getDragVisualizeOffset(), d.dragView.getDragRegion());
+            } else if (!folder && !mReorderAlarm.alarmPending() &&
+                    (mLastReorderX != reorderPosition[0] || mLastReorderY != reorderPosition[1])) {
+                // Otherwise, if we aren't adding to or creating a folder and there's no pending
+                // reorder, then we schedule a reorder
                 cancelFolderCreation();
                 ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter,
                         minSpanX, minSpanY, item.spanX, item.spanY, d.dragView, child);
@@ -2776,18 +2813,10 @@
                 if (mReorderAlarm != null) {
                     mReorderAlarm.cancelAlarm();
                 }
+                mDragTargetLayout.revertTempState();
+                mLastReorderX = -1;
+                mLastReorderY = -1;
             }
-            // TODO: need to determine what we're going to about visualizing drop locations
-            /*
-            boolean resize = resultSpan[0] != info.spanX || resultSpan[1] != info.spanY;
-            if (!folder) {
-                mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
-                        (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
-                        mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], resize,
-                        d.dragView.getDragVisualizeOffset(), d.dragView.getDragRegion());
-
-            }
-            */
         }
     }
 
@@ -2808,6 +2837,7 @@
         if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
             FolderIcon fi = ((FolderIcon) dragOverView);
             mDragMode = DRAG_MODE_ADD_TO_FOLDER;
+            mWillAddToExistingFolder = true;
             fi.onDragEnter(info);
             if (targetLayout != null) {
                 targetLayout.clearDragOutlines();
@@ -2817,12 +2847,13 @@
         if (dragOverView != lastDragOverView || (mCreateUserFolderOnDrop && !userFolderPending)
                 || (!willAddToFolder && mDragMode == DRAG_MODE_ADD_TO_FOLDER)) {
             cancelFolderCreation();
+            mWillAddToExistingFolder = false;
             if (lastDragOverView != null && lastDragOverView instanceof FolderIcon) {
                 ((FolderIcon) lastDragOverView).onDragExit(info);
             }
         }
 
-        return willAddToFolder || userFolderPending;
+        return (willAddToFolder || userFolderPending) && mDragMode != DRAG_MODE_REORDER;
     }
 
     private void cleanupFolderCreation(DragObject d) {
@@ -2889,25 +2920,28 @@
 
         public void onAlarm(Alarm alarm) {
             int[] resultSpan = new int[2];
+            mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
+                    (int) mDragViewVisualCenter[1], spanX, spanY, mDragTargetLayout, mTargetCell);
+            mLastReorderX = mTargetCell[0];
+            mLastReorderY = mTargetCell[1];
+
             mTargetCell = mDragTargetLayout.createArea((int) mDragViewVisualCenter[0],
                 (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
                 child, mTargetCell, resultSpan, CellLayout.MODE_DRAG_OVER);
 
-            mLastReorderX = mTargetCell[0];
-            mLastReorderY = mTargetCell[1];
+            if (mTargetCell[0] < 0 || mTargetCell[1] < 0) {
+                mDragTargetLayout.revertTempState();
+            }
 
             if (mDragMode == DRAG_MODE_ADD_TO_FOLDER) {
             }
             mDragMode = DRAG_MODE_REORDER;
 
-            // TODO: need to determine what we're going to about visualizing drop locations
-            /*
             boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY;
             mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
                 (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
                 mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], resize,
                 dragView.getDragVisualizeOffset(), dragView.getDragRegion());
-            */
         }
     }
 
@@ -2927,7 +2961,7 @@
             onDropExternal(dragInfo.dropPos, (ItemInfo) dragInfo, (CellLayout) layout, false);
             return true;
         }
-        mLauncher.showOutOfSpaceMessage();
+        mLauncher.showOutOfSpaceMessage(mLauncher.isHotseatLayout(layout));
         return false;
     }
 
@@ -3079,7 +3113,7 @@
                 // when dragging and dropping, just find the closest free spot
                 mTargetCell = mDragTargetLayout.createArea((int) mDragViewVisualCenter[0],
                         (int) mDragViewVisualCenter[1], 1, 1, 1, 1,
-                        null, mTargetCell, null, CellLayout.MODE_ON_DROP);
+                        null, mTargetCell, null, CellLayout.MODE_ON_DROP_EXTERNAL);
             } else {
                 cellLayout.findCellForSpan(mTargetCell, 1, 1);
             }
@@ -3280,7 +3314,8 @@
     /**
      * Called at the end of a drag which originated on the workspace.
      */
-    public void onDropCompleted(View target, DragObject d, boolean success) {
+    public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
+            boolean success) {
         if (success) {
             if (target != this) {
                 if (mDragInfo != null) {
@@ -3309,38 +3344,47 @@
         mDragOutline = null;
         mDragInfo = null;
 
-        saveWorkspaceStateToDb();
         // Hide the scrolling indicator after you pick up an item
         hideScrollingIndicator(false);
     }
 
-    public void saveWorkspaceStateToDb() {
-        int count = getChildCount();
+    void updateItemLocationsInDatabase(CellLayout cl) {
+        int count = cl.getShortcutsAndWidgets().getChildCount();
+
+        int screen = indexOfChild(cl);
+        int container = Favorites.CONTAINER_DESKTOP;
+
+        if (mLauncher.isHotseatLayout(cl)) {
+            screen = -1;
+            container = Favorites.CONTAINER_HOTSEAT;
+        }
+
         for (int i = 0; i < count; i++) {
-            CellLayout cl = (CellLayout) getChildAt(i);
-            if (cl.isItemPlacementDirty()) {
-                updateItemLocationsInDatabase(cl);
-                cl.setItemPlacementDirty(false);
+            View v = cl.getShortcutsAndWidgets().getChildAt(i);
+            ItemInfo info = (ItemInfo) v.getTag();
+            // Null check required as the AllApps button doesn't have an item info
+            if (info != null) {
+                LauncherModel.moveItemInDatabase(mLauncher, info, container, screen, info.cellX,
+                        info.cellY);
             }
         }
     }
 
-    private void updateItemLocationsInDatabase(CellLayout cl) {
-        int count = cl.getShortcutsAndWidgets().getChildCount();
-        int screen = indexOfChild(cl);
-        for (int i = 0; i < count; i++) {
-            View v = cl.getShortcutsAndWidgets().getChildAt(i);
-            ItemInfo info = (ItemInfo) v.getTag();
-
-            LauncherModel.moveItemInDatabase(mLauncher, info, Favorites.CONTAINER_DESKTOP, screen,
-                        info.cellX, info.cellY);
-        }
-    }
-
+    @Override
     public boolean supportsFlingToDelete() {
         return true;
     }
 
+    @Override
+    public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+        // Do nothing
+    }
+
+    @Override
+    public void onFlingToDeleteCompleted() {
+        // Do nothing
+    }
+
     public boolean isDropEnabled() {
         return true;
     }
@@ -3376,7 +3420,8 @@
     @Override
     public boolean onEnterScrollArea(int x, int y, int direction) {
         // Ignore the scroll area if we are dragging over the hot seat
-        if (mLauncher.getHotseat() != null) {
+        boolean isPortrait = !LauncherApplication.isScreenLandscape(getContext());
+        if (mLauncher.getHotseat() != null && isPortrait) {
             Rect r = new Rect();
             mLauncher.getHotseat().getHitRect(r);
             if (r.contains(x, y)) {