diff -BwurN cv126212/indra/newview/llfloateropenobject.cpp cv126212-patched/indra/newview/llfloateropenobject.cpp
--- cv126212/indra/newview/llfloateropenobject.cpp	2011-06-30 14:25:32.000000000 +0200
+++ cv126212-patched/indra/newview/llfloateropenobject.cpp	2012-01-10 14:17:18.000000000 +0100
@@ -160,13 +160,26 @@
 	{
 		parent_category_id = gAgent.getInventoryRootID();
 	}
+
+	LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
 	LLUUID category_id = gInventory.createNewCategory(parent_category_id, 
 		LLFolderType::FT_NONE, 
-		name);
+													  name,
+													  callbackCreateInventoryCategory,
+													  (void*)cat_data);
+
+
+	// If we get a null category ID, we are using a capability in
+	// createNewCategory and we will handle the following in the
+	// callbackCreateInventoryCategory routine.
+	if (category_id.notNull())
+	{
+		delete cat_data;
 
 	LLCatAndWear* data = new LLCatAndWear;
 	data->mCatID = category_id;
 	data->mWear = wear;
+		data->mFolderResponded = false;
 
 	// Copy and/or move the items into the newly created folder.
 	// Ignore any "you're going to break this item" messages.
@@ -181,6 +194,35 @@
 		LLNotifications::instance().add("OpenObjectCannotCopy");
 	}
 }
+}
+
+// static
+void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
+{
+	LLCategoryCreate* cat_data = (LLCategoryCreate*)data;
+
+	LLUUID category_id = result["folder_id"].asUUID();
+	LLCatAndWear* wear_data = new LLCatAndWear;
+
+	wear_data->mCatID = category_id;
+	wear_data->mWear = cat_data->mWear;
+	wear_data->mFolderResponded = true;
+
+ 	// 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(cat_data->mObjectID, category_id, TRUE,
+ 													callbackMoveInventory, 
+													(void*)wear_data);
+ 	if (!success)
+ 	{
+		delete wear_data;
+		wear_data = NULL;
+
+ 		LLNotifications::instance().add("OpenObjectCannotCopy");
+ 	}
+	delete cat_data;	
+ }
 
 // static
 void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
diff -BwurN cv126212/indra/newview/llfloateropenobject.h cv126212-patched/indra/newview/llfloateropenobject.h
--- cv126212/indra/newview/llfloateropenobject.h	2010-07-14 12:31:09.000000000 +0200
+++ cv126212-patched/indra/newview/llfloateropenobject.h	2012-01-10 14:17:18.000000000 +0100
@@ -50,10 +50,24 @@
 	static void show();
 	static void dirty();
 	
+	class LLCategoryCreate
+	{
+		public:
+			LLCategoryCreate(LLUUID object_id, bool wear)
+			:	mObjectID(object_id),
+				mWear(wear)
+			{}
+
+		public:
+			LLUUID mObjectID;
+			bool mWear;
+	};
+
 	struct LLCatAndWear
 	{
 		LLUUID mCatID;
 		bool mWear;
+		bool mFolderResponded;
 	};
 
 protected:
@@ -67,6 +81,7 @@
 
 	static void onClickMoveToInventory(void* data);
 	static void onClickMoveAndWear(void* data);
+	static void callbackCreateInventoryCategory(const LLSD& result, void* data);
 	static void callbackMoveInventory(S32 result, void* data);
 	static void* createPanelInventory(void* data);
 
diff -BwurN cv126212/indra/newview/llinventorybridge.cpp cv126212-patched/indra/newview/llinventorybridge.cpp
--- cv126212/indra/newview/llinventorybridge.cpp	2011-11-24 12:20:04.000000000 +0100
+++ cv126212-patched/indra/newview/llinventorybridge.cpp	2012-01-10 14:17:57.000000000 +0100
@@ -1854,18 +1854,21 @@
 class LLInventoryCopyAndWearObserver : public LLInventoryObserver
 {
 public:
-	LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {}
+	LLInventoryCopyAndWearObserver(const LLUUID& cat_id,
+								   int count,
+								   bool folder_added = false)
+	:	mCatID(cat_id),
+		mContentsCount(count),
+		mFolderAdded(FALSE) {}
 	virtual ~LLInventoryCopyAndWearObserver() {}
 	virtual void changed(U32 mask);
 
 protected:
 	LLUUID mCatID;
 	int    mContentsCount;
-	BOOL   mFolderAdded;
+	bool   mFolderAdded;
 };
 
-
-
 void LLInventoryCopyAndWearObserver::changed(U32 mask)
 {
 	if((mask & (LLInventoryObserver::ADD)) != 0)
@@ -2605,13 +2608,16 @@
 
 	if(option == 0 && object)
 	{
-		if (cat_and_wear && cat_and_wear->mWear)
+		if (cat_and_wear && cat_and_wear->mWear) // && !cat_and_wear->mFolderResponded)
 		{
 			InventoryObjectList inventory_objects;
 			object->getInventoryContents(inventory_objects);
 			int contents_count = inventory_objects.size()-1; //subtract one for containing folder
 
-			LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count);
+			LLInventoryCopyAndWearObserver* inventoryObserver;
+			inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID,
+																   contents_count,
+																   cat_and_wear->mFolderResponded);
 			gInventory.addObserver(inventoryObserver);
 		}
 
diff -BwurN cv126212/indra/newview/llinventorymodel.cpp cv126212-patched/indra/newview/llinventorymodel.cpp
--- cv126212/indra/newview/llinventorymodel.cpp	2011-12-25 23:17:00.000000000 +0100
+++ cv126212-patched/indra/newview/llinventorymodel.cpp	2012-01-10 14:18:38.000000000 +0100
@@ -359,13 +359,64 @@
 	return LLUUID::null;
 }
 
+class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
+{
+public:
+	LLCreateInventoryCategoryResponder(LLInventoryModel* model, 
+									   void (*callback)(const LLSD&, void*),
+									   void* user_data)
+	:	mModel(model),
+		mCallback(callback), 
+		mData(user_data) 
+	{
+	}
+
+	virtual void error(U32 status, const std::string& reason)
+	{
+		llwarns << "CreateInventoryCategory failed. status = " << status
+				<< ", reason = \"" << reason << "\"" << llendl;
+	}
+
+	virtual void result(const LLSD& content)
+	{
+		// Server has created folder.
+
+		LLUUID category_id = content["folder_id"].asUUID();
+
+		// Add the category to the internal representation
+		LLPointer<LLViewerInventoryCategory> cat;
+		cat = new LLViewerInventoryCategory(category_id,
+											content["parent_id"].asUUID(),
+											(LLFolderType::EType)content["type"].asInteger(),
+											content["name"].asString(), 
+											gAgent.getID());
+		cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+		cat->setDescendentCount(0);
+		LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+		mModel->accountForUpdate(update);
+		mModel->updateCategory(cat);
+
+		if (mCallback && mData)
+		{
+			mCallback(content, mData);
+		}
+	}
+
+private:
+	void (*mCallback)(const LLSD&, void*);
+	void* mData;
+	LLInventoryModel* mModel;
+};
+
 // Convenience function to create a new category. You could call
 // updateCategory() with a newly generated UUID category, but this
 // version will take care of details like what the name should be
 // based on preferred type. Returns the UUID of the new category.
 LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 										   LLFolderType::EType preferred_type,
-										   const std::string& pname)
+										   const std::string& pname,
+										   void (*callback)(const LLSD&, void*),
+										   void* user_data)
 {
 	LLUUID id;
 	if(!isInventoryUsable())
@@ -391,6 +442,37 @@
 		name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type));
 	}
 
+	if (callback && user_data)  // callback required for acked message.
+	{
+		LLViewerRegion* viewer_region = gAgent.getRegion();
+		std::string url;
+		if (viewer_region)
+		{
+			url = viewer_region->getCapability("CreateInventoryCategory");
+		}
+	
+		if (!url.empty())
+		{
+			LL_DEBUGS("Inventory") << "Using the CreateInventoryCategory capability."
+								   << LL_ENDL;
+			// Let's use the new capability.
+			LLSD request, body;
+			body["folder_id"] = id;
+			body["parent_id"] = parent_id;
+			body["type"] = (LLSD::Integer) preferred_type;
+			body["name"] = name;
+
+			request["message"] = "CreateInventoryCategory";
+			request["payload"] = body;
+
+			LLHTTPClient::post(url, body,
+							   new LLCreateInventoryCategoryResponder(this,
+																	  callback,
+																	  user_data));
+			return LLUUID::null;
+		}
+	}
+
 	// Add the category to the internal representation
 	LLPointer<LLViewerInventoryCategory> cat =
 		new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID());
@@ -2946,7 +3028,7 @@
 		//		<< titem->getParentUUID() << llendl;
 		U32 callback_id;
 		msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id);
-		if(titem->getUUID().notNull())
+		if (titem->getUUID().notNull()) // && callback_id.notNull())
 		{
 			items.push_back(titem);
 			cblist.push_back(InventoryCallbackInfo(callback_id, titem->getUUID()));
diff -BwurN cv126212/indra/newview/llinventorymodel.h cv126212-patched/indra/newview/llinventorymodel.h
--- cv126212/indra/newview/llinventorymodel.h	2011-11-03 17:23:43.000000000 +0100
+++ cv126212-patched/indra/newview/llinventorymodel.h	2012-01-10 14:17:18.000000000 +0100
@@ -312,7 +312,9 @@
 	// pass in a NULL to the 'name parameter.
 	LLUUID createNewCategory(const LLUUID& parent_id,
 							 LLFolderType::EType preferred_type,
-							 const std::string& name);
+							 const std::string& name,
+							 void (*callback)(const LLSD&, void*) = NULL,
+							 void* user_data = NULL);
 
 	// methods to load up inventory skeleton & meat. These are used
 	// during authentication. return true if everything parsed.
diff -BwurN cv126212/indra/newview/llviewerregion.cpp cv126212-patched/indra/newview/llviewerregion.cpp
--- cv126212/indra/newview/llviewerregion.cpp	2011-10-05 20:04:27.000000000 +0200
+++ cv126212-patched/indra/newview/llviewerregion.cpp	2012-01-10 14:17:18.000000000 +0100
@@ -1410,6 +1410,7 @@
 	LLSD capabilityNames = LLSD::emptyArray();
 	capabilityNames.append("ChatSessionRequest");
 	capabilityNames.append("CopyInventoryFromNotecard");
+	capabilityNames.append("CreateInventoryCategory");
 	capabilityNames.append("DispatchRegionInfo");
 	capabilityNames.append("EstateChangeInfo");
 	capabilityNames.append("EventQueueGet");
