diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index de52f3a18d0f742b6750ed64ff2932a532a8dcbc..1ede6bc1c91885dd51472f060e28764239af073e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -46,6 +46,7 @@
 #include "llviewerregion.h"
 #include "llcallbacklist.h"
 #include "llvoavatarself.h"
+#include <typeinfo>
 
 //#define DIFF_INVENTORY_FILES
 #ifdef DIFF_INVENTORY_FILES
@@ -3003,6 +3004,44 @@ void LLInventoryModel::removeItem(const LLUUID& item_id)
 	}
 }
 
+void LLInventoryModel::removeCategory(const LLUUID& category_id)
+{
+	LLViewerInventoryCategory* cat = getCategory(category_id);
+	if (! cat)
+	{
+		LL_WARNS("Inventory") << "couldn't find inventory folder " << category_id << LL_ENDL;
+	}
+	else
+	{
+		const LLUUID new_parent = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+		LL_INFOS("Inventory") << "Moving to Trash (" << new_parent << "):" << LL_ENDL;
+		changeCategoryParent(cat, new_parent, TRUE);
+	}
+}
+
+void LLInventoryModel::removeObject(const LLUUID& object_id)
+{
+	LLInventoryObject* obj = getObject(object_id);
+	if (dynamic_cast<LLViewerInventoryItem*>(obj))
+	{
+		removeItem(object_id);
+	}
+	else if (dynamic_cast<LLViewerInventoryCategory*>(obj))
+	{
+		removeCategory(object_id);
+	}
+	else if (obj)
+	{
+		LL_WARNS("Inventory") << "object ID " << object_id
+							  << " is an object of unrecognized class "
+							  << typeid(*obj).name() << LL_ENDL;
+	}
+	else
+	{
+		LL_WARNS("Inventory") << "object ID " << object_id << " not found" << LL_ENDL;
+	}
+}
+
 const LLUUID &LLInventoryModel::getRootFolderID() const
 {
 	return mRootFolderID;
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index f4602ce922e87d78fbd9a871e0fe0a6d0efcba81..8382e875b48690a67c87feefa92ea03747aac248 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -325,8 +325,13 @@ class LLInventoryModel
 	// consistent internal state. No cache accounting, observer
 	// notification, or server update is performed.
 	void deleteObject(const LLUUID& id);
+	/// move Item item_id to Trash
 	void removeItem(const LLUUID& item_id);
-	
+	/// move Category category_id to Trash
+	void removeCategory(const LLUUID& category_id);
+	/// removeItem() or removeCategory(), whichever is appropriate
+	void removeObject(const LLUUID& object_id);
+
 	// Delete a particular inventory object by ID, and delete it from
 	// the server. Also updates linked items.
 	void purgeObject(const LLUUID& id);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 3c6770df43fd84747e6f904f473b4ae7cce1b9e6..ed5dd845862bba49a50a23076785c96ddbf02f63 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1064,7 +1064,9 @@ class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
 		// If we now try to remove the inventory item, it will cause a nested
 		// notifyObservers() call, which won't work.
 		// So defer moving the item to trash until viewer gets idle (in a moment).
-		LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeItem, &gInventory, mObjectID));
+		// Use removeObject() rather than removeItem() because at this level,
+		// the object could be either an item or a folder.
+		LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeObject, &gInventory, mObjectID));
 		gInventory.removeObserver(this);
 		delete this;
 	}