diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 73eaced562452a3e55f038b1e82374e5893f0e85..d3ab22f792fb1cc79209ed6d2bf6015fbdab402e 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -184,9 +184,14 @@ void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category
 	
 	// Copy and/or move the items into the newly created folder.
 	// Ignore any "you're going to break this item" messages.
-	BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
-													callbackMoveInventory, 
-													(void*)wear_data);
+	BOOL success = move_inv_category_world_to_agent(object_id,
+                                                    category_id,
+                                                    TRUE,
+                                                    [](S32 result, void* data, const LLMoveInv*)
+                                                    {
+                                                        callbackMoveInventory(result, data);
+                                                    },
+                                                    (void*)wear_data);
 	if (!success)
 	{
 		delete wear_data;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e8c4a1ae021b83b65ebc29cff29603901dc7c5dd..49b6275c3ea0704048b8b048cb1245c72b487a2b 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -168,43 +168,57 @@ class LLPasteIntoFolderCallback: public LLInventoryCallback
     LLPasteIntoFolderCallback(LLHandle<LLInventoryPanel>& handle)
         : mInventoryPanel(handle)
     {
-        LLInventoryPanel* panel = mInventoryPanel.get();
-        if (panel)
-        {
-            panel->clearSelection();
-        }
     }
     ~LLPasteIntoFolderCallback()
     {
-        LLInventoryPanel* panel = mInventoryPanel.get();
-        if (panel && panel->getRootFolder()->getSelectedCount() > 0)
-        {
-            panel->getRootFolder()->scrollToShowSelection();
-        }
+        processItems();
     }
 
     void fire(const LLUUID& inv_item)
     {
-        LLInventoryItem* item = gInventory.getItem(inv_item);
+        mChangedIds.push_back(inv_item);
+    }
+
+    void processItems()
+    {
         LLInventoryPanel* panel = mInventoryPanel.get();
-        if (item && panel)
+        bool has_elements = false;
+        for (LLUUID& inv_item : mChangedIds)
         {
-            LLUUID root_id = panel->getRootFolderID();
-
-            if (inv_item == root_id)
+            LLInventoryItem* item = gInventory.getItem(inv_item);
+            if (item && panel)
             {
-                return;
-            }
+                LLUUID root_id = panel->getRootFolderID();
 
-            LLFolderViewItem* item = panel->getItemByID(inv_item);
-            if (item)
-            {
-                panel->getRootFolder()->changeSelection(item, TRUE);
+                if (inv_item == root_id)
+                {
+                    return;
+                }
+
+                LLFolderViewItem* item = panel->getItemByID(inv_item);
+                if (item)
+                {
+                    if (!has_elements)
+                    {
+                        panel->clearSelection();
+                        panel->getRootFolder()->clearSelection();
+                        panel->getRootFolder()->requestArrange();
+                        panel->getRootFolder()->update();
+                        has_elements = true;
+                    }
+                    panel->getRootFolder()->changeSelection(item, TRUE);
+                }
             }
         }
+
+        if (has_elements)
+        {
+            panel->getRootFolder()->scrollToShowSelection();
+        }
     }
 private:
     LLHandle<LLInventoryPanel> mInventoryPanel;
+    std::vector<LLUUID> mChangedIds;
 };
 
 // +=================================================+
@@ -2557,7 +2571,8 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 											BOOL drop,
 											std::string& tooltip_msg,
 											BOOL is_link,
-											BOOL user_confirm)
+											BOOL user_confirm,
+                                            LLPointer<LLInventoryCallback> cb)
 {
 
 	LLInventoryModel* model = getInventoryModel();
@@ -2862,7 +2877,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 			{
 				// Category can contains objects,
 				// create a new folder and populate it with links to original objects
-				dropToMyOutfits(inv_cat);
+				dropToMyOutfits(inv_cat, cb);
 			}
 			// if target is current outfit folder we use link
 			else if (move_is_into_current_outfit &&
@@ -2872,10 +2887,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 				// traverse category and add all contents to currently worn.
 				BOOL append = true;
 				LLAppearanceMgr::instance().wearInventoryCategory(inv_cat, false, append);
+                if (cb) cb->fire(inv_cat->getUUID());
 			}
 			else if (move_is_into_marketplacelistings)
 			{
 				move_folder_to_marketplacelistings(inv_cat, mUUID);
+                if (cb) cb->fire(inv_cat->getUUID());
 			}
 			else
 			{
@@ -2891,6 +2908,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 					(LLViewerInventoryCategory*)inv_cat,
 					mUUID,
 					move_is_into_trash);
+                if (cb) cb->fire(inv_cat->getUUID());
 			}
             if (move_is_from_marketplacelistings)
             {
@@ -2922,6 +2940,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
                     }
                     // In all cases, update the listing we moved from so suffix are updated
                     update_marketplace_category(from_folder_uuid);
+                    if (cb) cb->fire(inv_cat->getUUID());
                 }
             }
 		}
@@ -2935,7 +2954,19 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 		}
 		else
 		{
-			accept = move_inv_category_world_to_agent(cat_id, mUUID, drop, NULL, NULL, filter);
+            // Todo: fix me. moving from task inventory doesn't have a completion callback,
+            // yet making a copy creates new item id so this doesn't work right
+            std::function<void(S32, void*, const LLMoveInv*)> callback = [cb](S32, void*, const LLMoveInv* move_inv) mutable
+            {
+                two_uuids_list_t::const_iterator move_it;
+                for (move_it = move_inv->mMoveList.begin();
+                     move_it != move_inv->mMoveList.end();
+                     ++move_it)
+                {
+                    cb->fire(move_it->second);
+                }
+            };
+			accept = move_inv_category_world_to_agent(cat_id, mUUID, drop, callback, NULL, filter);
 		}
 	}
 	else if (LLToolDragAndDrop::SOURCE_LIBRARY == source)
@@ -3006,7 +3037,7 @@ void warn_move_inventory(LLViewerObject* object, boost::shared_ptr<LLMoveInv> mo
 BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 									  const LLUUID& category_id,
 									  BOOL drop,
-									  void (*callback)(S32, void*),
+									  std::function<void(S32, void*, const LLMoveInv*)> callback,
 									  void* user_data,
 									  LLInventoryFilter* filter)
 {
@@ -3859,7 +3890,6 @@ void LLFolderBridge::perform_pasteFromClipboard()
 		const BOOL move_is_into_favorites = (mUUID == favorites_id);
 		const BOOL move_is_into_lost_and_found = model->isObjectDescendentOf(mUUID, lost_and_found_id);
 
-        std::vector<LLUUID> result;
 		std::vector<LLUUID> objects;
 		LLClipboard::instance().pasteFromClipboard(objects);
 
@@ -3987,7 +4017,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
                             {
                                 //changeItemParent() implicity calls dirtyFilter
                                 changeItemParent(model, viitem, parent_id, FALSE);
-                                result.push_back(item_id);
+                                if (cb) cb->fire(item_id);
                             }
                         }
                         else
@@ -4020,7 +4050,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
                                 //changeCategoryParent() implicity calls dirtyFilter
                                 changeCategoryParent(model, vicat, parent_id, FALSE);
                             }
-                            result.push_back(item_id);
+                            if (cb) cb->fire(item_id);
 						}
 					}
 					else
@@ -4042,7 +4072,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
                                 //changeItemParent() implicity calls dirtyFilter
                                 changeItemParent(model, viitem, parent_id, FALSE);
                             }
-                            result.push_back(item_id);
+                            if (cb) cb->fire(item_id);
                         }
                     }
 				}
@@ -4063,7 +4093,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
                             {
                                 copy_inventory_category(model, vicat, parent_id);
                             }
-                            result.push_back(item_id);
+                            if (cb) cb->fire(item_id);
 						}
 					}
                     else
@@ -4079,12 +4109,13 @@ void LLFolderBridge::perform_pasteFromClipboard()
                                     // Stop pasting into the marketplace as soon as we get an error
                                     break;
                                 }
-                                result.push_back(item_id);
+                                if (cb) cb->fire(item_id);
                             }
                             else if (item->getIsLinkType())
                             {
-                                link_inventory_object(parent_id, item_id,
-                                    cb);
+                                link_inventory_object(parent_id,
+                                                      item_id,
+                                                      cb);
                             }
                             else
                             {
@@ -4103,14 +4134,6 @@ void LLFolderBridge::perform_pasteFromClipboard()
         }
 		// Change mode to paste for next paste
 		LLClipboard::instance().setCutMode(false);
-
-        if (cb.notNull())
-        {
-            for (LLUUID& pasted_id : result)
-            {
-                cb->fire(pasted_id);
-            }
-        }
 	}
 }
 
@@ -4594,6 +4617,18 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 {
 	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
 
+    static LLPointer<LLInventoryCallback> drop_cb = NULL;
+    LLInventoryPanel* panel = mInventoryPanel.get();
+    LLToolDragAndDrop* drop_tool = LLToolDragAndDrop::getInstance();
+    if (drop
+        && panel->getRootFolder()->isSingleFolderMode()
+        && panel->getRootFolderID() == mUUID
+        && drop_tool->getCargoIndex() == 0)
+    {
+        drop_cb = new LLPasteIntoFolderCallback(mInventoryPanel);
+    }
+
+
 	//LL_INFOS() << "LLFolderBridge::dragOrDrop()" << LL_ENDL;
 	BOOL accept = FALSE;
 	switch(cargo_type)
@@ -4611,7 +4646,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 		case DAD_GESTURE:
 		case DAD_MESH:
         case DAD_SETTINGS:
-			accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
+			accept = dragItemIntoFolder(inv_item, drop, tooltip_msg, TRUE, drop_cb);
 			break;
 		case DAD_LINK:
 			// DAD_LINK type might mean one of two asset types: AT_LINK or AT_LINK_FOLDER.
@@ -4622,12 +4657,12 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 				LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID());
 				if (linked_category)
 				{
-					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE);
+					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE, TRUE, drop_cb);
 				}
 			}
 			else
 			{
-				accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
+				accept = dragItemIntoFolder(inv_item, drop, tooltip_msg, TRUE, drop_cb);
 			}
 			break;
 		case DAD_CATEGORY:
@@ -4637,7 +4672,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 			}
 			else
 			{
-				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg);
+				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg, FALSE, TRUE, drop_cb);
 			}
 			break;
 		case DAD_ROOT_CATEGORY:
@@ -4647,6 +4682,11 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 			LL_WARNS() << "Unhandled cargo type for drag&drop " << cargo_type << LL_ENDL;
 			break;
 	}
+
+    if (!drop || drop_tool->getCargoIndex() + 1 == drop_tool->getCargoCount())
+    {
+        drop_cb = NULL;
+    }
 	return accept;
 }
 
@@ -4947,7 +4987,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
 
 	if (move_inv->mCallback)
 	{
-		move_inv->mCallback(option, move_inv->mUserData);
+		move_inv->mCallback(option, move_inv->mUserData, move_inv.get());
 	}
 
 	move_inv.reset(); //since notification will persist
@@ -5091,7 +5131,8 @@ void LLFolderBridge::callback_dropCategoryIntoFolder(const LLSD& notification, c
 BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 										BOOL drop,
 										std::string& tooltip_msg,
-                                        BOOL user_confirm)
+                                        BOOL user_confirm,
+                                        LLPointer<LLInventoryCallback> cb)
 {
 	LLInventoryModel* model = getInventoryModel();
 
@@ -5271,19 +5312,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			// (copy the item)
 			else if (move_is_into_favorites)
 			{
-				dropToFavorites(inv_item);
+				dropToFavorites(inv_item, cb);
 			}
 			// CURRENT OUTFIT or OUTFIT folder
 			// (link the item)
 			else if (move_is_into_current_outfit || move_is_into_outfit)
 			{
-				dropToOutfit(inv_item, move_is_into_current_outfit);
+				dropToOutfit(inv_item, move_is_into_current_outfit, cb);
 			}
             // MARKETPLACE LISTINGS folder
             // Move the item
             else if (move_is_into_marketplacelistings)
             {
                 move_item_to_marketplacelistings(inv_item, mUUID);
+                if (cb) cb->fire(inv_item->getUUID());
             }
 			// NORMAL or TRASH folder
 			// (move the item, restamp if into trash)
@@ -5300,6 +5342,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 					(LLViewerInventoryItem*)inv_item,
 					mUUID,
 					move_is_into_trash);
+                if (cb) cb->fire(inv_item->getUUID());
 			}
             
             if (move_is_from_marketplacelistings)
@@ -5384,11 +5427,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 
 		if (accept && drop)
 		{
+            LLUUID item_id = inv_item->getUUID();
             boost::shared_ptr<LLMoveInv> move_inv (new LLMoveInv());
 			move_inv->mObjectID = inv_item->getParentUUID();
-			two_uuids_t item_pair(mUUID, inv_item->getUUID());
+			two_uuids_t item_pair(mUUID, item_id);
 			move_inv->mMoveList.push_back(item_pair);
-			move_inv->mCallback = NULL;
+            if (cb)
+            {
+                move_inv->mCallback = [item_id, cb](S32, void*, const LLMoveInv* move_inv) mutable
+                    { cb->fire(item_id); };
+            }
 			move_inv->mUserData = NULL;
 			if(is_move)
 			{
@@ -5480,13 +5528,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				// (copy the item)
 				if (move_is_into_favorites)
 				{
-					dropToFavorites(inv_item);
+					dropToFavorites(inv_item, cb);
 				}
 				// CURRENT OUTFIT or OUTFIT folder
 				// (link the item)
 				else if (move_is_into_current_outfit || move_is_into_outfit)
 				{
-					dropToOutfit(inv_item, move_is_into_current_outfit);
+					dropToOutfit(inv_item, move_is_into_current_outfit, cb);
 				}
 				else
 				{
@@ -5496,7 +5544,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 						inv_item->getUUID(),
 						mUUID,
 						std::string(),
-						LLPointer<LLInventoryCallback>(NULL));
+						cb);
 				}
 			}
 		}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 7653208d90ee7a4aaa77eac8341e1e25509113d6..decaee7db3cd5369005a236d6c0d28edd5b76d25 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -46,6 +46,7 @@ class LLMenuGL;
 class LLCallingCardObserver;
 class LLViewerJointAttachment;
 class LLFolderView;
+struct LLMoveInv;
 
 typedef std::vector<std::string> menuentry_vec_t;
 typedef std::pair<LLUUID, LLUUID> two_uuids_t;
@@ -279,8 +280,8 @@ class LLFolderBridge : public LLInvFVBridge
 		mShowDescendantsCount(false)
 	{}
 		
-	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
-	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE);
+	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
+	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
     void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
     void callback_dropCategoryIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryCategory* inv_category);
 
@@ -747,7 +748,7 @@ void rez_attachment(LLViewerInventoryItem* item,
 BOOL move_inv_category_world_to_agent(const LLUUID& object_id, 
 									  const LLUUID& category_id,
 									  BOOL drop,
-									  void (*callback)(S32, void*) = NULL,
+									  std::function<void(S32, void*, const LLMoveInv *)> callback = NULL,
 									  void* user_data = NULL,
 									  LLInventoryFilter* filter = NULL);
 
@@ -778,7 +779,7 @@ struct LLMoveInv
     LLUUID mObjectID;
     LLUUID mCategoryID;
     two_uuids_list_t mMoveList;
-    void (*mCallback)(S32, void*);
+    std::function<void(S32, void*, const LLMoveInv*)> mCallback;
     void* mUserData;
 };