diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 4d7fc41ae351dfaab2f474737f592a92a9e4b5ba..02ca331bffaeaa50b54f6e88bb1438354f43365a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2430,7 +2430,7 @@ BOOL LLFolderBridge::isItemRemovable(bool check_worn) const
 	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ?   panel->getItemByID(mUUID) : NULL);
 	if (folderp)
 	{
-		LLIsItemRemovable folder_test;
+		LLIsItemRemovable folder_test(check_worn);
 		folderp->applyFunctorToChildren(folder_test);
 		if (!folder_test.mPassed)
 		{
@@ -6626,6 +6626,26 @@ LLInventoryObject* LLObjectBridge::getObject() const
 	return object;
 }
 
+LLViewerInventoryItem* LLObjectBridge::getItem() const
+{
+    LLInventoryModel* model = getInventoryModel();
+    if (model)
+    {
+       return model->getItem(mUUID);
+    }
+    return NULL;
+}
+
+LLViewerInventoryCategory* LLObjectBridge::getCategory() const
+{
+    LLInventoryModel* model = getInventoryModel();
+    if (model)
+    {
+        return model->getCategory(mUUID);
+    }
+    return NULL;
+}
+
 // virtual
 void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 {
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 62e26b2f285e63f21aa9996d48a696116d95066e..0d87e2b97c84e3187b6c42bfe4cffea110ad4169 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -524,6 +524,8 @@ class LLObjectBridge : public LLItemBridge
 	virtual void			buildContextMenu(LLMenuGL& menu, U32 flags);
 	virtual BOOL renameItem(const std::string& new_name);
 	LLInventoryObject* getObject() const;
+    LLViewerInventoryItem* getItem() const;
+    LLViewerInventoryCategory* getCategory() const;
 protected:
 	static LLUUID sContextMenuItemID;  // Only valid while the context menu is open.
 	U32 mAttachPt;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 5e702ef75537fcac7c734d52da08e9e0e02d7e1c..849f6417580bae08b920d8f2597f86c1365b6e40 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -579,9 +579,8 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id)
 	return FALSE;
 }
 
-BOOL get_is_item_worn(const LLUUID& id)
+BOOL get_is_item_worn(const LLUUID& id, const LLViewerInventoryItem* item)
 {
-	const LLViewerInventoryItem* item = gInventory.getItem(id);
 	if (!item)
 		return FALSE;
 
@@ -619,6 +618,21 @@ BOOL get_is_item_worn(const LLUUID& id)
 	return FALSE;
 }
 
+BOOL get_is_item_worn(const LLUUID& id)
+{
+    const LLViewerInventoryItem* item = gInventory.getItem(id);
+    return get_is_item_worn(item);
+}
+
+BOOL get_is_item_worn(const LLViewerInventoryItem* item)
+{
+    if (!item)
+    {
+        return FALSE;
+    }
+    return get_is_item_worn(item->getUUID(), item);
+}
+
 BOOL get_can_item_be_worn(const LLUUID& id)
 {
 	const LLViewerInventoryItem* item = gInventory.getItem(id);
@@ -3034,15 +3048,47 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 				folder->applyFunctorRecursively(f);
 			}
 			LLFolderViewModelItemInventory * viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
-			if (viewModel && gInventory.isObjectDescendentOf(viewModel->getUUID(), marketplacelistings_id))
+            LLUUID obj_id = viewModel->getUUID();
+			if (viewModel && gInventory.isObjectDescendentOf(obj_id, marketplacelistings_id))
 			{
 				marketplacelistings_item = true;
 				break;
 			}
-            if (get_is_item_worn(viewModel->getUUID()))
+
+            LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+            if (cat)
+            {
+                LLInventoryModel::cat_array_t categories;
+                LLInventoryModel::item_array_t items;
+
+                gInventory.collectDescendents(obj_id, categories, items, FALSE);
+
+                for (LLInventoryModel::item_array_t::value_type& item : items)
+                {
+                    if (get_is_item_worn(item))
+                    {
+                        has_worn = true;
+                        LLWearableType::EType type = item->getWearableType();
+                        if (type == LLWearableType::WT_SHAPE
+                            || type == LLWearableType::WT_SKIN
+                            || type == LLWearableType::WT_HAIR
+                            || type == LLWearableType::WT_EYES)
+                        {
+                            needs_replacement = true;
+                            break;
+                        }
+                    }
+                }
+                if (needs_replacement)
+                {
+                    break;
+                }
+            }
+            LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+            if (item && get_is_item_worn(item))
             {
                 has_worn = true;
-                LLWearableType::EType type = viewModel->getWearableType();
+                LLWearableType::EType type = item->getWearableType();
                 if (type == LLWearableType::WT_SHAPE
                     || type == LLWearableType::WT_SKIN
                     || type == LLWearableType::WT_HAIR
@@ -3381,6 +3427,7 @@ void LLInventoryAction::removeItemFromDND(LLFolderView* root)
         }
     }
 }
+
 void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -3394,6 +3441,7 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
 
         // removeSelectedItems will change selection, collect worn items beforehand
         uuid_vec_t worn;
+        uuid_vec_t deletion_list;
         if (has_worn)
         {
             //Get selected items
@@ -3403,18 +3451,42 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
             //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
             for (LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
             {
-                LLObjectBridge* view_model = dynamic_cast<LLObjectBridge*>((*it)->getViewModelItem());
+                LLFolderViewModelItemInventory* viewModel = dynamic_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem());
+
+                LLUUID obj_id = viewModel->getUUID();
+                LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+                bool cat_has_worn = false;
+                if (cat)
+                {
+                    LLInventoryModel::cat_array_t categories;
+                    LLInventoryModel::item_array_t items;
+
+                    gInventory.collectDescendents(obj_id, categories, items, FALSE);
 
-                if (view_model && get_is_item_worn(view_model->getUUID()))
+                    for (LLInventoryModel::item_array_t::value_type& item : items)
+                    {
+                        if (get_is_item_worn(item))
+                        {
+                            worn.push_back(item->getUUID());
+                            cat_has_worn = true;
+                        }
+                    }
+                    if (cat_has_worn)
+                    {
+                        deletion_list.push_back(obj_id);
+                    }
+                }
+                LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+                if (item && get_is_item_worn(item))
                 {
-                    worn.push_back(view_model->getUUID());
+                    worn.push_back(obj_id);
+                    deletion_list.push_back(obj_id);
                 }
             }
         }
-        // TODO: collect worn items from content and folders that neede to be deleted after that
 
         // removeSelectedItems will check if items are worn before deletion,
-        // don't 'unwear' yet to prevent a race condition from unwearing
+        // don't 'unwear' yet to prevent race conditions from unwearing
         // and removing simultaneously
         folder_root->removeSelectedItems();
 
@@ -3423,9 +3495,9 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
         {
             // should fire once after every item gets detached
             LLAppearanceMgr::instance().removeItemsFromAvatar(worn,
-                                                              [worn]()
+                                                              [deletion_list]()
                                                               {
-                                                                  for (const LLUUID& id : worn)
+                                                                  for (const LLUUID& id : deletion_list)
                                                                   {
                                                                       remove_inventory_item(id, NULL);
                                                                   }
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index cac1d77f5e8b72e60d75db62a1897201d4716676..a8a9bb9735387a9ba309578f4fdab6b156676304 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -47,6 +47,7 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id);
 
 // Is this item or its baseitem is worn, attached, etc...
 BOOL get_is_item_worn(const LLUUID& id);
+BOOL get_is_item_worn(const LLViewerInventoryItem* item);
 
 // Could this item be worn (correct type + not already being worn)
 BOOL get_can_item_be_worn(const LLUUID& id);