diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 8b6619def2f1db6eb3bdc3e86975eb1fe34f398d..4bfef8b45fae6ff58b26e57f116ade9b25dc6785 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -162,26 +162,66 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
 	{
 		parent_category_id = gInventory.getRootFolderID();
 	}
+	
+	LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
+	
 	LLUUID category_id = gInventory.createNewCategory(parent_category_id, 
-		LLFolderType::FT_NONE, 
-		name);
+													  LLFolderType::FT_NONE, 
+													  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.
+		BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
+														callbackMoveInventory, 
+														(void*)data);
+		if (!success)
+		{
+			delete data;
+			data = NULL;
 
-	LLCatAndWear* data = new LLCatAndWear;
-	data->mCatID = category_id;
-	data->mWear = wear;
+			LLNotificationsUtil::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(object_id, category_id, TRUE,
+	BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE,
 													callbackMoveInventory, 
-													(void*)data);
+													(void*)wear_data);
 	if (!success)
 	{
-		delete data;
-		data = NULL;
-
+		delete wear_data;
+		wear_data = NULL;
+		
 		LLNotificationsUtil::add("OpenObjectCannotCopy");
 	}
+	delete cat_data;	
 }
 
 // static
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 0706e99f16493544e84ab5fe4e79aec7fd080eb5..bf7fe69c656fbad1bb9e4b9d7f9a926a34aed5a3 100644
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -45,10 +45,20 @@ class LLFloaterOpenObject
 	
 	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:
@@ -62,6 +72,7 @@ class LLFloaterOpenObject
 
 	void onClickMoveToInventory();
 	void onClickMoveAndWear();
+	static void callbackCreateInventoryCategory(const LLSD& result, void* data);
 	static void callbackMoveInventory(S32 result, void* data);
 
 private:
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0c092e9a561fd7526f20046fbc66e4d9711a01ef..eaf9b53eb91e8f707c1f09b60fa41e69309b7f0b 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2305,15 +2305,15 @@ void LLRightClickInventoryFetchDescendentsObserver::done()
 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(folder_added) {}
 	virtual ~LLInventoryCopyAndWearObserver() {}
 	virtual void changed(U32 mask);
 
 protected:
 	LLUUID mCatID;
 	int    mContentsCount;
-	BOOL   mFolderAdded;
+	bool   mFolderAdded;
 };
 
 
@@ -2341,7 +2341,6 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
 		if (mFolderAdded)
 		{
 			LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
-
 			if (NULL == category)
 			{
 				llwarns << "gInventory.getCategory(" << mCatID
@@ -3188,13 +3187,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
 
 	if(option == 0 && object)
 	{
-		if (cat_and_wear && cat_and_wear->mWear)
+		if (cat_and_wear && cat_and_wear->mWear) // && !cat_and_wear->mFolderResponded)
 		{
 			LLInventoryObject::object_list_t 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 = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded);
+			
 			gInventory.addObserver(inventoryObserver);
 		}
 
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index dc25689fa3f58391df5d24512a7c15846797ee82..568ec4c5e20f7977e944bcabba1857711056c78b 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -377,14 +377,67 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 	return rv;
 }
 
+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)
+	{
+		LL_WARNS("InvAPI") << "CreateInventoryCategory failed.   status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+	}
+	
+	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 =
+		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*),	//Default to NULL
+										   void* user_data)							//Default to NULL
 {
+	
 	LLUUID id;
 	if(!isInventoryUsable())
 	{
@@ -408,6 +461,35 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 	{
 		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())
+		{
+			//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;
+			
+	//		viewer_region->getCapAPI().post(request);
+			LLHTTPClient::post(
+							   url,
+							   body,
+							   new LLCreateInventoryCategoryResponder(this, callback, user_data) );
+			return LLUUID::null;
+		}
+	}
 
 	// Add the category to the internal representation
 	LLPointer<LLViewerInventoryCategory> cat =
@@ -1087,7 +1169,6 @@ void LLInventoryModel::notifyObservers()
 		 iter != mObservers.end(); )
 	{
 		LLInventoryObserver* observer = *iter;
-		
 		observer->changed(mModifyMask);
 
 		// safe way to increment since changed may delete entries! (@!##%@!@&*!)
@@ -2574,7 +2655,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
 				<< 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 --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 340c1b0c22d389600d201c22ec7a9a81afdc44cb..0a564d353a0f7782baa3d640d330aa50d9bd25f4 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -360,7 +360,9 @@ class LLInventoryModel
 	// name based on type, 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 );
 protected:
 	// Internal methods that add inventory and make sure that all of
 	// the internal data structures are consistent. These methods
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ed943964f9ae61df12cbe58424b05a6c7b5632e1..e3cb985ddb3a35bab24412d0d2a6f5d20f9613b0 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1493,6 +1493,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("AvatarPickerSearch");
 	capabilityNames.append("ChatSessionRequest");
 	capabilityNames.append("CopyInventoryFromNotecard");
+	capabilityNames.append("CreateInventoryCategory");
 	capabilityNames.append("DispatchRegionInfo");
 	capabilityNames.append("EstateChangeInfo");
 	capabilityNames.append("EventQueueGet");