diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 1f948abfae69f2d4eed545b43cfbb45f4b8fd535..cae04ccb49cf08518adbda4c9b645bb671e17867 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -984,7 +984,7 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
 									 const LLUUID& new_parent_id,
 									 BOOL restamp)
 {
-	change_item_parent(model, item, new_parent_id, restamp);
+	model->changeItemParent(item, new_parent_id, restamp);
 }
 
 // static
@@ -993,7 +993,7 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
 										 const LLUUID& new_parent_id,
 										 BOOL restamp)
 {
-	change_category_parent(model, cat, new_parent_id, restamp);
+	model->changeCategoryParent(cat, new_parent_id, restamp);
 }
 
 LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index f74a239fd330ff6899800dcc12c551b22a466161..629fa53388b18e06c79fc24966ec40316dd389c5 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -108,58 +108,6 @@ void append_path(const LLUUID& id, std::string& path)
 	path.append(temp);
 }
 
-void change_item_parent(LLInventoryModel* model,
-						LLViewerInventoryItem* item,
-						const LLUUID& new_parent_id,
-						BOOL restamp)
-{
-	if (item->getParentUUID() != new_parent_id)
-	{
-		LLInventoryModel::update_list_t update;
-		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
-		update.push_back(old_folder);
-		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
-		update.push_back(new_folder);
-		gInventory.accountForUpdate(update);
-
-		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
-		new_item->setParent(new_parent_id);
-		new_item->updateParentOnServer(restamp);
-		model->updateItem(new_item);
-		model->notifyObservers();
-	}
-}
-
-void change_category_parent(LLInventoryModel* model,
-	LLViewerInventoryCategory* cat,
-	const LLUUID& new_parent_id,
-	BOOL restamp)
-{
-	if (!model || !cat)
-	{
-		return;
-	}
-
-	// Can't move a folder into a child of itself.
-	if (model->isObjectDescendentOf(new_parent_id, cat->getUUID()))
-	{
-		return;
-	}
-
-	LLInventoryModel::update_list_t update;
-	LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
-	update.push_back(old_folder);
-	LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
-	update.push_back(new_folder);
-	model->accountForUpdate(update);
-
-	LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
-	new_cat->setParent(new_parent_id);
-	new_cat->updateParentOnServer(restamp);
-	model->updateCategory(new_cat);
-	model->notifyObservers();
-}
-
 // Move the item to the trash. Works for folders and objects.
 // Caution: This method assumes that the item is removable!
 void remove_item(LLInventoryModel* model, const LLUUID& id)
@@ -214,7 +162,7 @@ void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
 	if (cat)
 	{
 		const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
-		change_category_parent(model, cat, trash_id, TRUE);
+		model->changeCategoryParent(cat, trash_id, TRUE);
 	}
 }
 
@@ -635,8 +583,7 @@ void move_to_outbox_cb_action(const LLSD& payload)
 
 		LLUUID parent = viitem->getParentUUID();
 
-		change_item_parent(
-			&gInventory,
+		gInventory.changeItemParent(
 			viitem,
 			dest_folder_id,
 			false);
@@ -737,7 +684,7 @@ void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32
 	
 	LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
 
-	change_item_parent(&gInventory,
+	gInventory.changeItemParent(
 					   viewer_inv_item,
 					   dest_folder,
 					   false);
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index b3d9f4b966a383d87abb0641266bd338d6c0674e..535d831e477f46f897f483d6cfba78873d68a9f6 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -57,18 +57,8 @@ void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id);
 
 void show_item_original(const LLUUID& item_uuid);
 
-void change_item_parent(LLInventoryModel* model,
-									 LLViewerInventoryItem* item,
-									 const LLUUID& new_parent_id,
-									 BOOL restamp);
-
 void remove_item(LLInventoryModel* model, const LLUUID& id);
 
-void change_category_parent(LLInventoryModel* model,
-	LLViewerInventoryCategory* cat,
-	const LLUUID& new_parent_id,
-	BOOL restamp);
-
 void remove_category(LLInventoryModel* model, const LLUUID& cat_id);
 
 void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 0eba8bd0f1aa3ceae8a1020e93557d40c2f7ce3e..1ea4cb63f6dc047393dc208fb48ea2c192fd98ce 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -47,6 +47,7 @@
 #include "llviewerregion.h"
 #include "llcallbacklist.h"
 #include "llvoavatarself.h"
+#include <typeinfo>
 
 //#define DIFF_INVENTORY_FILES
 #ifdef DIFF_INVENTORY_FILES
@@ -1018,6 +1019,66 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id)
 	}
 }
 
+// Migrated from llinventoryfunctions
+void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item,
+										const LLUUID& new_parent_id,
+										BOOL restamp)
+{
+	if (item->getParentUUID() == new_parent_id)
+	{
+		LL_DEBUGS("Inventory") << "'" << item->getName() << "' (" << item->getUUID()
+							   << ") is already in folder " << new_parent_id << LL_ENDL;
+	}
+	else
+	{
+		LL_INFOS("Inventory") << "Moving '" << item->getName() << "' (" << item->getUUID()
+							  << ") from " << item->getParentUUID() << " to folder "
+							  << new_parent_id << LL_ENDL;
+		LLInventoryModel::update_list_t update;
+		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
+		update.push_back(old_folder);
+		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+		update.push_back(new_folder);
+		accountForUpdate(update);
+
+		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+		new_item->setParent(new_parent_id);
+		new_item->updateParentOnServer(restamp);
+		updateItem(new_item);
+		notifyObservers();
+	}
+}
+
+// Migrated from llinventoryfunctions
+void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat,
+											const LLUUID& new_parent_id,
+											BOOL restamp)
+{
+	if (!cat)
+	{
+		return;
+	}
+
+	// Can't move a folder into a child of itself.
+	if (isObjectDescendentOf(new_parent_id, cat->getUUID()))
+	{
+		return;
+	}
+
+	LLInventoryModel::update_list_t update;
+	LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
+	update.push_back(old_folder);
+	LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+	update.push_back(new_folder);
+	accountForUpdate(update);
+
+	LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
+	new_cat->setParent(new_parent_id);
+	new_cat->updateParentOnServer(restamp);
+	updateCategory(new_cat);
+	notifyObservers();
+}
+
 // Delete a particular inventory object by ID.
 void LLInventoryModel::deleteObject(const LLUUID& id)
 {
@@ -2964,21 +3025,53 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLFolderT
 void LLInventoryModel::removeItem(const LLUUID& item_id)
 {
 	LLViewerInventoryItem* item = getItem(item_id);
-	const LLUUID new_parent = findCategoryUUIDForType(LLFolderType::FT_TRASH);
-	if (item && item->getParentUUID() != new_parent)
+	if (! item)
 	{
-		LLInventoryModel::update_list_t update;
-		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
-		update.push_back(old_folder);
-		LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
-		update.push_back(new_folder);
-		accountForUpdate(update);
+		LL_WARNS("Inventory") << "couldn't find inventory item " << item_id << LL_ENDL;
+	}
+	else
+	{
+		const LLUUID new_parent = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+		LL_INFOS("Inventory") << "Moving to Trash (" << new_parent << "):" << LL_ENDL;
+		changeItemParent(item, new_parent, TRUE);
+	}
+}
 
-		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
-		new_item->setParent(new_parent);
-		new_item->updateParentOnServer(TRUE);
-		updateItem(new_item);
-		notifyObservers();
+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;
 	}
 }
 
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 7cd85c4ab7bfd59aa1a0616136c9006f81a6f963..8382e875b48690a67c87feefa92ea03747aac248 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -306,6 +306,16 @@ class LLInventoryModel
 	// observer notification, or server update is performed.
 	void moveObject(const LLUUID& object_id, const LLUUID& cat_id);
 
+	// Migrated from llinventoryfunctions
+	void changeItemParent(LLViewerInventoryItem* item,
+						  const LLUUID& new_parent_id,
+						  BOOL restamp);
+
+	// Migrated from llinventoryfunctions
+	void changeCategoryParent(LLViewerInventoryCategory* cat,
+							  const LLUUID& new_parent_id,
+							  BOOL restamp);
+
 	//--------------------------------------------------------------------
 	// Delete
 	//--------------------------------------------------------------------
@@ -315,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/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 4974dde282c24044446503e184dbe3fc36ccd76b..3a9360fd23dbab67252ce95890ef83fb87fe83da 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -29,7 +29,6 @@
 #include "llpreviewnotecard.h"
 
 #include "llinventory.h"
-#include "llinventoryfunctions.h" // for change_item_parent()
 
 #include "llagent.h"
 #include "llassetuploadresponders.h"
@@ -494,7 +493,7 @@ void LLPreviewNotecard::deleteNotecard()
 	if (item != NULL)
 	{
 		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
-		change_item_parent(&gInventory, item, trash_id, FALSE);
+		gInventory.changeItemParent(item, trash_id, FALSE);
 	}
 
 	closeFloater();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index b7319fcef061bf5981ae8352b1b465690d2202c7..ae87e3da970557001473d2656563616622aef1d7 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1065,7 +1065,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;
 	}