diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af11bfe02406a63c035c346e8be0f81ad..884007d2a628fe5e16f7df3108856e350141625c 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -792,6 +792,19 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 			disabled_items.push_back(std::string("Copy"));
 		}
 
+        if (isAgentInventory())
+        {
+            items.push_back(std::string("New folder from selected"));
+            items.push_back(std::string("Subfolder Separator"));
+            std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+            uuid_vec_t ids;
+            std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+            if (!is_only_items_selected(ids) && !is_only_cats_selected(ids))
+            {
+                disabled_items.push_back(std::string("New folder from selected"));
+            }
+        }
+
 		if (obj->getIsLinkType())
 		{
 			items.push_back(std::string("Find Original"));
@@ -4266,7 +4279,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 			items.push_back(std::string("Conference Chat Folder"));
 			items.push_back(std::string("IM All Contacts In Folder"));
 		}
+
+        if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+        {
+            items.push_back(std::string("Ungroup folder items"));
+        }
 	}
+    else
+    {
+        disabled_items.push_back(std::string("New folder from selected"));
+    }
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d239b23e83da281636e8f275bdf9cc57f9841ae5..d8a4340254df3dbef22091c7dee14b146f3489c7 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1868,6 +1868,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
 	}
 }
 
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids)
+{
+    for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+    {
+        LLInventoryItem* inv_item = gInventory.getItem(*it);
+        if (inv_item)
+        {
+            change_item_parent(*it, new_cat_uuid);
+        }
+        else
+        {
+            LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+            if (inv_cat)
+            {
+                gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
+            }
+        }
+    }
+
+    LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+    if (!floater_inventory)
+    {
+        LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+        return;
+    }
+    LLSidepanelInventory *sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+    if (sidepanel_inventory)
+    {
+        if (sidepanel_inventory->getActivePanel())
+        {
+            sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES);
+            LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid);
+            if (fv_folder)
+            {
+                fv_folder->setOpen(TRUE);
+            }
+        }
+    }
+}
+
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids)
+{
+    for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+    {
+        LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+        if (!inv_cat)
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool is_only_items_selected(const uuid_vec_t& selected_uuids)
+{
+    for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+    {
+        LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+        if (!inv_item)
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name)
+{
+    LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin());
+    if (!first_item)
+    {
+        return;
+    }
+
+    inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids);
+    gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
+
+}
+
 ///----------------------------------------------------------------------------
 /// LLInventoryCollectFunctor implementations
 ///----------------------------------------------------------------------------
@@ -2522,6 +2602,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
     {
         (new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile();
     }
+    else if ("new_folder_from_selected" == action)
+    {
+
+        LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
+        if (!first_item)
+        {
+            return;
+        }
+        const LLUUID& parent_uuid = first_item->getParentUUID();
+        for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+        {
+            LLInventoryObject *item = gInventory.getObject(*it);
+            if (!item || item->getParentUUID() != parent_uuid)
+            {
+                LLNotificationsUtil::add("SameFolderRequired");
+                return;
+            }
+        }
+        
+        LLSD args;
+        args["DESC"] = LLTrans::getString("New Folder");
+ 
+        LLNotificationsUtil::add("CreateSubfolder", args, LLSD(),
+            [ids](const LLSD& notification, const LLSD& response)
+        {
+            S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+            if (opt == 0)
+            {
+                std::string settings_name = response["message"].asString();
+
+                LLInventoryObject::correctInventoryName(settings_name);
+                if (settings_name.empty())
+                {
+                    settings_name = LLTrans::getString("New Folder");
+                }
+                move_items_to_new_subfolder(ids, settings_name);
+            }
+        });
+    }
+    else if ("ungroup_folder_items" == action)
+    {
+        if (selected_uuid_set.size() == 1)
+        {
+            LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
+            if (!inv_cat)
+            {
+                return;
+            }
+            const LLUUID &new_cat_uuid = inv_cat->getParentUUID();
+            LLInventoryModel::cat_array_t* cat_array;
+            LLInventoryModel::item_array_t* item_array;
+            gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array);
+            LLInventoryModel::cat_array_t cats = *cat_array;
+            LLInventoryModel::item_array_t items = *item_array;
+
+            for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter)
+            {
+                LLViewerInventoryCategory* cat = *cat_iter;
+                if (cat)
+                {
+                    gInventory.changeCategoryParent(cat, new_cat_uuid, false);
+                }
+            }
+            for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter)
+            {
+                LLViewerInventoryItem* item = *item_iter;
+                if(item)
+                {
+                    gInventory.changeItemParent(item, new_cat_uuid, false);
+                }
+            }
+            gInventory.removeCategory(inv_cat->getUUID());
+            gInventory.notifyObservers();
+        }
+    }
     else
     {
         std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8915bfa1e050d26f224a88dc8b883ab6e83a4b68..ba9f157e47ba97b389c9a51d14a49c87d3a5fc36 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -93,6 +93,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
 S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
 
 void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name);
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
+bool is_only_items_selected(const uuid_vec_t& selected_uuids);
 
 /**                    Miscellaneous global functions
  **                                                                            **
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8baad30e8f09e0593a2e617cb34e283ab46e47a9..692e8d91a9c8d90c4cadc48447d4a4f1b52e78dc 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 			mLineEditor->setText(edit_text_contents);
 
 			std::string notif_name = mNotification->getName();
-			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
+			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
 			{
 				mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
 			}
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca1708132e602bb09997a8f471fe0ab3c1a47c..aa3d0ae071f466bf2a1fa598530ed787ed584517 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -912,6 +912,25 @@
                 function="Inventory.DoToSelected"
                 parameter="apply_settings_parcel" />
     </menu_item_call>
+  <menu_item_separator
+   layout="topleft"
+   name="Subfolder Separator" />
+  <menu_item_call
+   label="Create folder from selected"
+   layout="topleft"
+   name="New folder from selected">
+    <menu_item_call.on_click
+     function="Inventory.DoToSelected"
+     parameter="new_folder_from_selected" />
+  </menu_item_call>
+  <menu_item_call
+   label="Ungroup folder items"
+   layout="topleft"
+   name="Ungroup folder items">
+    <menu_item_call.on_click
+     function="Inventory.DoToSelected"
+     parameter="ungroup_folder_items" />
+  </menu_item_call>
 	<menu_item_separator
 	 layout="topleft"
 	 name="Marketplace Separator" />
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6a9039b198dfe308ae5f9b7cd4894b86e1d14642..0a3826123c3b032843046865bfbbcde8d0ce719e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11842,4 +11842,38 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
     </form>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   label="Save Outfit"
+   name="CreateSubfolder"
+   type="alertmodal">
+    <unique/>
+    Name the new folder:
+    <tag>confirm</tag>
+    <form name="form">
+      <input name="message" type="text">
+        [DESC]
+      </input>
+      <button
+       default="true"
+       index="0"
+       name="OK"
+       text="OK"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
+  <notification
+   icon="alertmodal.tga"
+   name="SameFolderRequired"
+   type="alert">
+    Selected items must be in the same folder.
+    <tag>fail</tag>
+    <usetemplate
+      name="okbutton"
+      yestext="OK"/>
+  </notification>
+
 </notifications>