diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 78edcb3e25eaaa1701633a60e4d0f298d681d90e..27290533909121ea1938cce13653c9a14d30e022 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1275,6 +1275,11 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)
 // static
 bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)
 {
+	if (gAgentWearables.isCOFChangeInProgress())
+	{
+		return false;
+	}
+
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
 	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
@@ -1286,6 +1291,32 @@ bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)
 	return items.size() > 0;
 }
 
+bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
+{
+	// Don't allow wearing anything while we're changing appearance.
+	if (gAgentWearables.isCOFChangeInProgress())
+	{
+		return false;
+	}
+
+	// Check whether it's the base outfit.
+	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
+	{
+		return false;
+	}
+
+	// Check whether the outfit contains any non-worn wearables.
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
+	gInventory.collectDescendentsIf(outfit_cat_id,
+		cats,
+		items,
+		LLInventoryModel::EXCLUDE_TRASH,
+		not_worn);
+	return items.size() > 0;
+}
+
 void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
 {
 	LLInventoryModel::cat_array_t cats;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 9f554dbdef3d1d8b1276bbba46708a0be046f117..eb495bd2746360a5edeea209dace5886a5cdd024 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -84,6 +84,9 @@ public:
 	// Determine whether we can add anything (but body parts) from the outfit contents to COF.
 	static bool getCanAddToCOF(const LLUUID& outfit_cat_id);
 
+	// Determine whether we can replace current outfit with the given one.
+	bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
+
 	// Copy all items in a category.
 	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
 									 LLPointer<LLInventoryCallback> cb);
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 893400185c216c1833570f27c8f5fd319fee3fb8..eb950bf6c13dfc9726bb022202451f1afdf5005f 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -163,7 +163,7 @@ public:
 	}
 
 protected:
-	static void replaceWearable()
+	static void replaceWearable(const LLUUID& item_id)
 	{
 		// *TODO: Most probable that accessing to LLPanelOutfitEdit instance should be:
 		// LLSideTray::getInstance()->getSidepanelAppearance()->getPanelOutfitEdit()
@@ -175,7 +175,7 @@ protected:
 								"panel_outfit_edit"));
 		if (panel_outfit_edit != NULL)
 		{
-			panel_outfit_edit->showAddWearablesPanel(true);
+			panel_outfit_edit->onReplaceMenuItemClicked(item_id);
 		}
 	}
 
@@ -187,7 +187,7 @@ protected:
 		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
 
 		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
-		registrar.add("Clothing.Replace", boost::bind(replaceWearable));
+		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));
 		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
 		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));
 
@@ -244,7 +244,7 @@ protected:
 		// *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel().
 		// LLSideTray::getInstance()->getPanel() is rather slow variant
 		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit"));
-		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));
+		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceMenuItemClicked, panel_oe, selected_id));
 		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
 		registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id));
 
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 8147a973173b53a210621e181405644445336438..f921bca623261d89cc72638036c6751e0e1df18e 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -275,11 +275,10 @@ protected:
 		}
 		else if ("wear_replace" == param)
 		{
-			return !gAgentWearables.isCOFChangeInProgress();
+			return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id);
 		}
 		else if ("wear_add" == param)
 		{
-			if (gAgentWearables.isCOFChangeInProgress()) return false;
 			return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id);
 		}
 		else if ("take_off" == param)
@@ -676,7 +675,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
 		}
 
 		// outfit selected
-		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
+		return LLAppearanceMgr::instance().getCanReplaceCOF(mSelectedOutfitUUID);
 	}
 	if (command_name == "take_off")
 	{
@@ -689,11 +688,6 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
 	if (command_name == "wear_add")
 	{
 		// *TODO: do we ever get here?
-		if (gAgentWearables.isCOFChangeInProgress())
-		{
-			return false;
-		}
-
 		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
 	}
 
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 8b9baef54ae84549c7e61ceaecc5e8aba5ec123d..c12f1fbe99956f6eaa959454dc947bf429e562cf 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -609,11 +609,11 @@ void LLPanelOutfitEdit::onAddWearableClicked(void)
 	}
 }
 
-void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id)
+void LLPanelOutfitEdit::onReplaceMenuItemClicked(LLUUID selected_item_id)
 {
 	LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
 
-	if (item && item->getType() == LLAssetType::AT_BODYPART)
+	if (item)
 	{
 		showFilteredWearablesListView(item->getWearableType());
 	}
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 0efc6dc1890b4a0fb50da6a3f19b1af4c63fee55..5ce707e6ebed6fe94572df9f3e518eaedb1571ed 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -164,7 +164,7 @@ public:
 	void onRemoveFromOutfitClicked(void);
 	void onEditWearableClicked(void);
 	void onAddWearableClicked(void);
-	void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id);
+	void onReplaceMenuItemClicked(LLUUID selected_item_id);
 	void onShopButtonClicked();
 
 	void displayCurrentOutfit();