diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 0874f574c55e025c86d45bb9a59f1d7c150e9208..aa7c8c789aa4a300215d33753af1a8c500e76a5e 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1338,7 +1338,7 @@ LLImageFormatted::LLImageFormatted(S8 codec)
 	  mCodec(codec),
 	  mDecoding(0),
 	  mDecoded(0),
-	  mDiscardLevel(0)
+	  mDiscardLevel(-1)
 {
 	mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
 }
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index e09b511a6e475ace147d16ea9e3e6343a0e42cf9..0c9b325b68b91a74bfacf769bd45aaa98f8a6043 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void)
 		mPlugin->idle();
 	}
 	
-	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL))
+	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
 	{
 		// Can't process a size change at this time
 	}
@@ -437,6 +437,12 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
 {
 	if(type == MOUSE_EVENT_MOVE)
 	{
+		if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked())
+		{
+			// Don't queue up mouse move events that can't be delivered.
+			return;
+		}
+
 		if((x == mLastMouseX) && (y == mLastMouseY))
 		{
 			// Don't spam unnecessary mouse move events.
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 1d7ddc55924c02f1728a8694a2db6cdbf9b8ba19..e524c88cf832d2db02a114f35e65c51509e90ba1 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -299,26 +299,23 @@ bool LLPluginMessagePipe::pump(F64 timeout)
 void LLPluginMessagePipe::processInput(void)
 {
 	// Look for input delimiter(s) in the input buffer.
-	int start = 0;
 	int delim;
-	while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos)
+	while((delim = mInput.find(MESSAGE_DELIMITER)) != std::string::npos)
 	{	
 		// Let the owner process this message
 		if (mOwner)
 		{
-			mOwner->receiveMessageRaw(mInput.substr(start, delim - start));
+			// Pull the message out of the input buffer before calling receiveMessageRaw.
+			// It's now possible for this function to get called recursively (in the case where the plugin makes a blocking request)
+			// and this guarantees that the messages will get dequeued correctly.
+			std::string message(mInput, 0, delim);
+			mInput.erase(0, delim + 1);
+			mOwner->receiveMessageRaw(message);
 		}
 		else
 		{
 			LL_WARNS("Plugin") << "!mOwner" << LL_ENDL;
 		}
-		
-		start = delim + 1;
 	}
-	
-	// Remove delivered messages from the input buffer.
-	if(start != 0)
-		mInput = mInput.substr(start);
-	
 }
 
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index ccaf95b36ded8c072865cb1a954041650126dce1..2d078cd6ed71d4c150c4d4b5a6eda4f0d7708291 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -48,6 +48,8 @@ LLPluginProcessChild::LLPluginProcessChild()
 	mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
 	mSleepTime = PLUGIN_IDLE_SECONDS;	// default: send idle messages at 100Hz
 	mCPUElapsed = 0.0f;
+	mBlockingRequest = false;
+	mBlockingResponseReceived = false;
 }
 
 LLPluginProcessChild::~LLPluginProcessChild()
@@ -226,6 +228,7 @@ void LLPluginProcessChild::idle(void)
 
 void LLPluginProcessChild::sleep(F64 seconds)
 {
+	deliverQueuedMessages();
 	if(mMessagePipe)
 	{
 		mMessagePipe->pump(seconds);
@@ -238,6 +241,7 @@ void LLPluginProcessChild::sleep(F64 seconds)
 
 void LLPluginProcessChild::pump(void)
 {
+	deliverQueuedMessages();
 	if(mMessagePipe)
 	{
 		mMessagePipe->pump(0.0f);
@@ -309,15 +313,32 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 
 	LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL;
 
+	// Decode this message
+	LLPluginMessage parsed;
+	parsed.parse(message);
+
+	if(mBlockingRequest)
+	{
+		// We're blocking the plugin waiting for a response.
+
+		if(parsed.hasValue("blocking_response"))
+		{
+			// This is the message we've been waiting for -- fall through and send it immediately. 
+			mBlockingResponseReceived = true;
+		}
+		else
+		{
+			// Still waiting.  Queue this message and don't process it yet.
+			mMessageQueue.push(message);
+			return;
+		}
+	}
+	
 	bool passMessage = true;
 	
 	// FIXME: how should we handle queueing here?
 	
 	{
-		// Decode this message
-		LLPluginMessage parsed;
-		parsed.parse(message);
-		
 		std::string message_class = parsed.getClass();
 		if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
 		{
@@ -425,7 +446,13 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 {
 	LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
-
+	
+	if(mBlockingRequest)
+	{
+		// 
+		LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL;
+	}
+	
 	// Incoming message from the plugin instance
 	bool passMessage = true;
 
@@ -436,6 +463,12 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 		// Decode this message
 		LLPluginMessage parsed;
 		parsed.parse(message);
+		
+		if(parsed.hasValue("blocking_request"))
+		{
+			mBlockingRequest = true;
+		}
+
 		std::string message_class = parsed.getClass();
 		if(message_class == "base")
 		{
@@ -494,6 +527,19 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 		LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
 		writeMessageRaw(message);
 	}
+	
+	while(mBlockingRequest)
+	{
+		// The plugin wants to block and wait for a response to this message.
+		sleep(mSleepTime);	// this will pump the message pipe and process messages
+
+		if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL))
+		{
+			// Response has been received, or we've hit an error state.  Stop waiting.
+			mBlockingRequest = false;
+			mBlockingResponseReceived = false;
+		}
+	}
 }
 
 
@@ -502,3 +548,15 @@ void LLPluginProcessChild::setState(EState state)
 	LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
 	mState = state; 
 };
+
+void LLPluginProcessChild::deliverQueuedMessages()
+{
+	if(!mBlockingRequest)
+	{
+		while(!mMessageQueue.empty())
+		{
+			receiveMessageRaw(mMessageQueue.front());
+			mMessageQueue.pop();
+		}
+	}
+}
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index 0e5e85406a671fa00f0b33ac1357e5ca17695e8a..1430ad7a5db5cf6f2e486562a9906d55f6e0977d 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -106,6 +106,11 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst
 	LLTimer mHeartbeat;
 	F64		mSleepTime;
 	F64		mCPUElapsed;
+	bool	mBlockingRequest;
+	bool	mBlockingResponseReceived;
+	std::queue<std::string> mMessageQueue;
+	
+	void deliverQueuedMessages();
 	
 };
 
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 895c858979026645dfc5632e6707ae2cc7fd773e..e273410a1d5f60ae3c01eaf2d4338dbaa9e56147 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -54,6 +54,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
 	mCPUUsage = 0.0;
 	mDisableTimeout = false;
 	mDebug = false;
+	mBlocked = false;
 
 	mPluginLaunchTimeout = 60.0f;
 	mPluginLockupTimeout = 15.0f;
@@ -479,6 +480,13 @@ void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send)
 
 void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
 {
+	if(message.hasValue("blocking_response"))
+	{
+		mBlocked = false;
+
+		// reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
+		mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
+	}
 	
 	std::string buffer = message.generate();
 	LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;	
@@ -501,6 +509,11 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
 
 void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
 {
+	if(message.hasValue("blocking_request"))
+	{
+		mBlocked = true;
+	}
+
 	std::string message_class = message.getClass();
 	if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
 	{
@@ -689,18 +702,15 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
 {
 	bool result = false;
 	
-	if(!mDisableTimeout && !mDebug)
+	if(!mProcess.isRunning())
 	{
-		if(!mProcess.isRunning())
-		{
-			LL_WARNS("Plugin") << "child exited" << llendl;
-			result = true;
-		}
-		else if(pluginLockedUp())
-		{
-			LL_WARNS("Plugin") << "timeout" << llendl;
-			result = true;
-		}
+		LL_WARNS("Plugin") << "child exited" << llendl;
+		result = true;
+	}
+	else if(pluginLockedUp())
+	{
+		LL_WARNS("Plugin") << "timeout" << llendl;
+		result = true;
 	}
 	
 	return result;
@@ -708,6 +718,12 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
 
 bool LLPluginProcessParent::pluginLockedUp()
 {
+	if(mDisableTimeout || mDebug || mBlocked)
+	{
+		// Never time out a plugin process in these cases.
+		return false;
+	}
+	
 	// If the timer is running and has expired, the plugin has locked up.
 	return (mHeartbeat.getStarted() && mHeartbeat.hasExpired());
 }
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index cc6c513615747283dfd71c9e504841168697ffb3..31f125bfb313eff2e9a09c2522611c2bee879e21 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -74,6 +74,9 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 	// returns true if the process has exited or we've had a fatal error
 	bool isDone(void);	
 	
+	// returns true if the process is currently waiting on a blocking request
+	bool isBlocked(void) { return mBlocked; };
+	
 	void killSockets(void);
 	
 	// Go to the proper error state
@@ -160,6 +163,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 	
 	bool mDisableTimeout;
 	bool mDebug;
+	bool mBlocked;
 
 	LLProcessLauncher mDebugger;
 	
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 491cd7b6f37564bd8690e895737e9e6fd7566bbe..b47f21ed8ae7609af5dc399f7034427916fba1d6 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -457,3 +457,8 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask)
 	return FALSE;
 }
 
+BOOL LLSpinCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	// just treat a double click as a second click
+	return handleMouseDown(x, y, mask);
+}
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 00d6f86f8375906245ebf6d23a01a403d43fa0ea..06201255d2d5fef12cd8343bf44fba69931cbfbe 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -94,6 +94,7 @@ class LLSpinCtrl
 
 	virtual BOOL	handleScrollWheel(S32 x,S32 y,S32 clicks);
 	virtual BOOL	handleKeyHere(KEY key, MASK mask);
+	virtual BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	void			onEditorCommit(const LLSD& data);
 	static void		onEditorGainFocus(LLFocusableElement* caller, void *userdata);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a820d82f6ff121b1ae70b01c68dee41ebe5344d0..4c0d47ced36d1fa606f79f35cbfc7dbd41dcad56 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5849,7 +5849,18 @@
         <key>Value</key>
             <real>1.0</real>
         </map>
-    <key>RecentItemsSortOrder</key>
+  <key>MediaRollOffFactor</key>
+  <map>
+    <key>Comment</key>
+    <string>Multiplier to change rate of media attenuation</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>10.0</real>
+  </map>
+  <key>RecentItemsSortOrder</key>
     <map>
       <key>Comment</key>
       <string>Specifies sort key for recent inventory items (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string>
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index e21644e119754f853cd7d875a262bb2bb44efde9..a2a1dd504a37287c11d6f41f75a5bbcb471bf2cf 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -89,6 +89,7 @@ void LLCOFWearables::onSelectionChange(LLFlatListView* selected_list)
 	onCommit();
 }
 
+#include "llwearableitemslist.h"
 void LLCOFWearables::refresh()
 {
 	clear();
@@ -117,16 +118,15 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel
 
 		const LLAssetType::EType item_type = item->getType();
 		if (item_type == LLAssetType::AT_CLOTHING) continue;
-
-		LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
-		if (!item_panel) continue;
-
+		LLPanelInventoryListItemBase* item_panel = NULL;
 		if (item_type == LLAssetType::AT_OBJECT)
 		{
+				item_panel = LLPanelInventoryListItemBase::create(item);
 			mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
 		}
 		else if (item_type == LLAssetType::AT_BODYPART)
 		{
+			item_panel = LLPanelBodyPartsListItem::create(item);
 			mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
 			addWearableTypeSeparator(mBodyParts);
 		}
@@ -165,7 +165,7 @@ void LLCOFWearables::populateClothingList(LLAppearanceMgr::wearables_by_type_t&
 		{
 			LLViewerInventoryItem* item = clothing_by_type[type][i];
 
-			LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
+			LLPanelInventoryListItemBase* item_panel = LLPanelClothingListItem::create(item);
 			if (!item_panel) continue;
 
 			mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index dca130c672996f010685abca88455f4e60f3bafd..3d8cb6dfe8e7792ab4acc01b4e8a0522257e6df6 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -50,76 +50,212 @@
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-// static
-LLPanelInventoryListItem* LLPanelInventoryListItem::createItemPanel(const LLViewerInventoryItem* item)
+static const S32 WIDGET_SPACING = 3;
+
+LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
 {
+	LLPanelInventoryListItemBase* list_item = NULL;
 	if (item)
 	{
-		return new LLPanelInventoryListItem(item);
+		list_item = new LLPanelInventoryListItemBase(item);
+		list_item->init();
 	}
-	else
+	return list_item;
+}
+
+void LLPanelInventoryListItemBase::updateItem()
+{
+	if (mItemIcon.notNull())
+		mIcon->setImage(mItemIcon);
+
+	LLTextUtil::textboxSetHighlightedVal(
+		mTitle,
+		LLStyle::Params(),
+		mItem->getName(),
+		mHighlightedText);
+}
+
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
+{
+	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
+	if(ctrl)
 	{
-		return NULL;
+		addWidgetToLeftSide(ctrl, show_widget);
 	}
 }
 
-LLPanelInventoryListItem::~LLPanelInventoryListItem()
-{}
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
+{
+	mLeftSideWidgets.push_back(ctrl);
+	setShowWidget(ctrl, show_widget);
+}
 
-//virtual
-BOOL LLPanelInventoryListItem::postBuild()
+void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/)
 {
+	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
+	if(ctrl)
+	{
+		addWidgetToRightSide(ctrl, show_widget);
+	}
+}
+
+void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
+{
+	mRightSideWidgets.push_back(ctrl);
+	setShowWidget(ctrl, show_widget);
+}
+
+void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show)
+{
+	LLUICtrl* widget = findChild<LLUICtrl>(name);
+	if(widget)
+	{
+		setShowWidget(widget, show);
+	}
+}
+
+void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
+{
+	// Enable state determines whether widget may become visible in setWidgetsVisible()
+	ctrl->setEnabled(show);
+}
+
+BOOL LLPanelInventoryListItemBase::postBuild()
+{
+	// Inheritors need to call base implementation
 	mIcon = getChild<LLIconCtrl>("item_icon");
 	mTitle = getChild<LLTextBox>("item_name");
 
 	updateItem();
 
+	setWidgetsVisible(false);
+	reshapeWidgets();
+
 	return TRUE;
 }
 
-//virtual
-void LLPanelInventoryListItem::setValue(const LLSD& value)
+void LLPanelInventoryListItemBase::setValue(const LLSD& value)
 {
 	if (!value.isMap()) return;
 	if (!value.has("selected")) return;
 	childSetVisible("selected_icon", value["selected"]);
 }
 
-void LLPanelInventoryListItem::updateItem()
+void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
 {
-	if (mItemIcon.notNull())
-		mIcon->setImage(mItemIcon);
+	childSetVisible("hovered_icon", true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
 
-	LLTextUtil::textboxSetHighlightedVal(
-		mTitle,
-		LLStyle::Params(),
-		mItemName,
-		mHighlightedText);
+void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	childSetVisible("hovered_icon", false);
+	LLPanel::onMouseLeave(x, y, mask);
 }
 
-void LLPanelInventoryListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
+: LLPanel()
+, mItem(item)
+, mIcon(NULL)
+, mTitle(NULL)
+, mWidgetSpacing(WIDGET_SPACING)
+, mLeftWidgetsWidth(0)
+, mRightWidgetsWidth(0)
 {
-	childSetVisible("hovered_icon", true);
+	mItemIcon = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
+}
 
-	LLPanel::onMouseEnter(x, y, mask);
+void LLPanelInventoryListItemBase::init()
+{
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
 }
 
-void LLPanelInventoryListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+class WidgetVisibilityChanger
 {
-	childSetVisible("hovered_icon", false);
+public:
+	WidgetVisibilityChanger(bool visible) : mVisible(visible){}
+	void operator()(LLUICtrl* widget)
+	{
+		// Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget()
+		widget->setVisible(mVisible && widget->getEnabled());
+	}
+private:
+	bool mVisible;
+};
 
-	LLPanel::onMouseLeave(x, y, mask);
+void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
+{
+	std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
+	std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
 }
 
-LLPanelInventoryListItem::LLPanelInventoryListItem(const LLViewerInventoryItem* item)
-:	 LLPanel()
-	,mIcon(NULL)
-	,mTitle(NULL)
+void LLPanelInventoryListItemBase::reshapeWidgets()
 {
-	mItemName = item->getName();
-	mItemIcon = get_item_icon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE);
+	// disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
+	/*reshapeLeftWidgets();*/
+	reshapeRightWidgets();
+	reshapeMiddleWidgets();
+}
 
-	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
+void LLPanelInventoryListItemBase::reshapeLeftWidgets()
+{
+	S32 widget_left = 0;
+	mLeftWidgetsWidth = 0;
+
+	widget_array_t::const_iterator it = mLeftSideWidgets.begin();
+	const widget_array_t::const_iterator it_end = mLeftSideWidgets.end();
+	for( ; it_end != it; ++it)
+	{
+		LLUICtrl* widget = *it;
+		if(!widget->getVisible())
+		{
+			continue;
+		}
+		LLRect widget_rect(widget->getRect());
+		widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
+		widget->setShape(widget_rect);
+
+		widget_left += widget_rect.getWidth() + getWidgetSpacing();
+		mLeftWidgetsWidth = widget_rect.mRight;
+	}
+}
+
+void LLPanelInventoryListItemBase::reshapeRightWidgets()
+{
+	S32 widget_right = getLocalRect().getWidth();
+	S32 widget_left = widget_right;
+
+	widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin();
+	const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend();
+	for( ; it_end != it; ++it)
+	{
+		LLUICtrl* widget = *it;
+		if(!widget->getVisible())
+		{
+			continue;
+		}
+		LLRect widget_rect(widget->getRect());
+		widget_left = widget_right - widget_rect.getWidth();
+		widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
+		widget->setShape(widget_rect);
+
+		widget_right = widget_left - getWidgetSpacing();
+	}
+	mRightWidgetsWidth = getLocalRect().getWidth() - widget_left;
+}
+
+void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
+{
+	LLRect icon_rect(mIcon->getRect());
+	icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, 
+		icon_rect.getWidth(), icon_rect.getHeight());
+	mIcon->setShape(icon_rect);
+
+	S32 name_left = icon_rect.mRight + getWidgetSpacing();
+	S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
+	LLRect name_rect(mTitle->getRect());
+	name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
+	mTitle->setShape(name_rect);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -223,7 +359,7 @@ void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)
 		llassert(!"No inventory item. Couldn't create flat list item.");
 	}
 
-	LLPanelInventoryListItem *list_item = LLPanelInventoryListItem::createItemPanel(item);
+	LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
 	if (!list_item)
 		return;
 
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index b496f4b9e94c74a24e16997154fa31bd010f4616..15f04c79a9775c330d82542c52b6e5847ab2cf89 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -47,33 +47,130 @@ class LLIconCtrl;
 class LLTextBox;
 class LLViewerInventoryItem;
 
-class LLPanelInventoryListItem : public LLPanel
+/**
+ * @class LLPanelInventoryListItemBase
+ *
+ * Base class for Inventory flat list item. Panel consists of inventory icon
+ * and inventory item name.
+ * This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides 
+ * of panel.
+ *
+ * How to use (see LLPanelClothingListItem for example):
+ * - implement init() to build panel from xml
+ * - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides
+ * - redefine postBuild()(call base implementation) and add needed widgets to needed sides,
+ *
+ */
+class LLPanelInventoryListItemBase : public LLPanel
 {
 public:
-	static LLPanelInventoryListItem* createItemPanel(const LLViewerInventoryItem* item);
 
-	virtual ~LLPanelInventoryListItem();
+	static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
+
+	/**
+	 * Called after inventory item was updated, update panel widgets to reflect inventory changes.
+	 */
+	virtual void updateItem();
+
+	/**
+	 * Add widget to left side
+	 */
+	void addWidgetToLeftSide(const std::string& name, bool show_widget = true);
+	void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true);
+
+	/**
+	 * Add widget to right side, widget is supposed to be child of calling panel
+	 */
+	void addWidgetToRightSide(const std::string& name, bool show_widget = true);
+	void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true);
+
+	/**
+	 * Mark widgets as visible. Only visible widgets take part in reshaping children
+	 */
+	void setShowWidget(const std::string& name, bool show);
+	void setShowWidget(LLUICtrl* ctrl, bool show);
+
+	/**
+	 * Set spacing between widgets during reshape
+	 */
+	void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; }
+
+	S32 getWidgetSpacing() { return mWidgetSpacing; }
 
+	/**
+	 * Inheritors need to call base implementation of postBuild()
+	 */
 	/*virtual*/ BOOL postBuild();
+
+	/**
+	 * Handles item selection
+	 */
 	/*virtual*/ void setValue(const LLSD& value);
 
-	void updateItem();
+	 /* Highlights item */
+	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+	/* Removes item highlight */
+	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
 
-	void onMouseEnter(S32 x, S32 y, MASK mask);
-	void onMouseLeave(S32 x, S32 y, MASK mask);
+	virtual ~LLPanelInventoryListItemBase(){}
 
 protected:
-	LLPanelInventoryListItem(const LLViewerInventoryItem* item);
+
+	LLPanelInventoryListItemBase(LLViewerInventoryItem* item);
+
+	typedef std::vector<LLUICtrl*> widget_array_t;
+
+	/**
+	 * Use it from a factory function to build panel, do not build panel in constructor
+	 */
+	virtual void init();
+
+	void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
+	void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; }
+
+	/**
+	 * Set all widgets from both side visible/invisible. Only enabled widgets
+	 * (see setShowWidget()) can become visible
+	 */
+	virtual void setWidgetsVisible(bool visible);
+
+	/**
+	 * Reshape all child widgets - icon, text-box and side widgets
+	 */
+	virtual void reshapeWidgets();
 
 private:
+
+	/** reshape left side widgets
+	 * Deprecated for now. Disabled reshape left for now to reserve space for 'delete' 
+	 * button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/)
+	 */
+	void reshapeLeftWidgets();
+
+	/** reshape right side widgets */
+	void reshapeRightWidgets();
+
+	/** reshape remaining widgets */
+	void reshapeMiddleWidgets();
+
+	LLViewerInventoryItem* mItem;
+
 	LLIconCtrl*		mIcon;
 	LLTextBox*		mTitle;
 
 	LLUIImagePtr	mItemIcon;
-	std::string		mItemName;
 	std::string		mHighlightedText;
+
+	widget_array_t	mLeftSideWidgets;
+	widget_array_t	mRightSideWidgets;
+	S32				mWidgetSpacing;
+
+	S32				mLeftWidgetsWidth;
+	S32				mRightWidgetsWidth;
 };
 
+//////////////////////////////////////////////////////////////////////////
+
 class LLInventoryItemsList : public LLFlatListView
 {
 public:
@@ -117,7 +214,7 @@ class LLInventoryItemsList : public LLFlatListView
 	/**
 	 * Add an item to the list
 	 */
-	void addNewItem(LLViewerInventoryItem* item);
+	virtual void addNewItem(LLViewerInventoryItem* item);
 
 private:
 	uuid_vec_t mIDs; // IDs of items that were added in refreshList().
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index e64696b12081d07dc2063eabb0edf8ea74e35ab9..3d447dd41125e7045e5ff9a00c5bc3a56bc19741 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -167,8 +167,6 @@ class LLTextureFetchWorker : public LLWorkerClass
 	}
 
 protected:
-	LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host,
-						 F32 priority, S32 discard, S32 size);
 	LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
 						 F32 priority, S32 discard, S32 size);
 
@@ -215,8 +213,15 @@ class LLTextureFetchWorker : public LLWorkerClass
 		QUEUED = 1,
 		SENT_SIM = 2
 	};
+	enum e_write_to_cache_state //mWriteToCacheState
+	{
+		NOT_WRITE = 0,
+		CAN_WRITE = 1,
+		SHOULD_WRITE = 2
+	};
 	static const char* sStateDescs[];
 	e_state mState;
+	e_write_to_cache_state mWriteToCacheState;
 	LLTextureFetch* mFetcher;
 	LLPointer<LLImageFormatted> mFormattedImage;
 	LLPointer<LLImageRaw> mRawImage;
@@ -377,6 +382,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 										   S32 size)			// Desired size
 	: LLWorkerClass(fetcher, "TextureFetch"),
 	  mState(INIT),
+	  mWriteToCacheState(NOT_WRITE),
 	  mFetcher(fetcher),
 	  mID(id),
 	  mHost(host),
@@ -595,7 +601,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	}
 
 	if (mState == INIT)
-	{
+	{		
 		mRawImage = NULL ;
 		mRequestedDiscard = -1;
 		mLoadedDiscard = -1;
@@ -636,17 +642,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mFileSize = 0;
 			mLoaded = FALSE;
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
-			CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
+			
 			if (mUrl.compare(0, 7, "file://") == 0)
 			{
 				// read file from local disk
 				std::string filename = mUrl.substr(7, std::string::npos);
+				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
 																		  offset, size, responder);
 			}
 			else if (mUrl.empty())
 			{
+				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
 																		  offset, size, responder);
 			}
@@ -659,8 +666,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				}
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 				mState = SEND_HTTP_REQ;
-				delete responder;
-				responder = NULL;
 			}
 		}
 
@@ -694,6 +699,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			llassert_always(mFormattedImage->getDataSize() > 0);
 			mLoadedDiscard = mDesiredDiscard;
 			mState = DECODE_IMAGE;
+			mWriteToCacheState = NOT_WRITE ;
 			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
 								 << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
 								 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
@@ -735,6 +741,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				if (!http_url.empty())
 				{
 					mUrl = http_url + "/?texture_id=" + mID.asString().c_str();
+					mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
 				}
 			}
 			else
@@ -747,12 +754,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		{
 			mState = LLTextureFetchWorker::SEND_HTTP_REQ;
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+			if(mWriteToCacheState != NOT_WRITE)
+			{
+				mWriteToCacheState = CAN_WRITE ;
+			}
 			// don't return, fall through to next state
 		}
 		else if (mSentRequest == UNSENT)
 		{
 			// Add this to the network queue and sit here.
 			// LLTextureFetch::update() will send off a request which will change our state
+			mWriteToCacheState = CAN_WRITE ;
 			mRequestedSize = mDesiredSize;
 			mRequestedDiscard = mDesiredDiscard;
 			mSentRequest = QUEUED;
@@ -789,6 +801,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			mState = DECODE_IMAGE;
+			mWriteToCacheState = SHOULD_WRITE ;
 		}
 		else
 		{
@@ -850,7 +863,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mState = WAIT_HTTP_REQ;	
 
 				mFetcher->addToHTTPQueue(mID);
-				mSentRequest = QUEUED;
 				// Will call callbackHttpGet when curl request completes
 				std::vector<std::string> headers;
 				headers.push_back("Accept: image/x-j2c");
@@ -933,15 +945,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			
 			llassert_always(mBufferSize == cur_size + mRequestedSize);
-			if (mHaveAllData)
+			if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded.
 			{
 				mFileSize = mBufferSize;
 			}
-			else //the file size is unknown
+			else //the file size is unknown.
 			{
-				mFileSize = S32_MAX ; //flag the file is not fully loaded.
+				mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.
 			}
-
+			
 			U8* buffer = new U8[mBufferSize];
 			if (cur_size > 0)
 			{
@@ -956,6 +968,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mBufferSize = 0;
 			mLoadedDiscard = mRequestedDiscard;
 			mState = DECODE_IMAGE;
+			if(mWriteToCacheState != NOT_WRITE)
+			{
+				mWriteToCacheState = SHOULD_WRITE ;
+			}
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			return false;
 		}
@@ -1055,7 +1071,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == WRITE_TO_CACHE)
 	{
-		if (mInLocalCache || mSentRequest == UNSENT || mFormattedImage.isNull())
+		if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull())
 		{
 			// If we're in a local cache or we didn't actually receive any new data,
 			// or we failed to load anything, skip
@@ -1063,6 +1079,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			return false;
 		}
 		S32 datasize = mFormattedImage->getDataSize();
+		if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
+		{
+			if(mHaveAllData)
+			{
+				mFileSize = datasize ;
+			}
+			else
+			{
+				mFileSize = datasize + 1 ; //flag not fully loaded.
+			}
+		}
 		llassert_always(datasize);
 		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 		U32 cache_priority = mWorkPriority;
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3c0345df90e2f80010f9b68b02d70e9279afae31..fd2bb0fdf9cdd771bed1fee7e54a637f927e7760 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1914,7 +1914,15 @@ void LLViewerMediaImpl::updateVolume()
 {
 	if(mMediaSource)
 	{
-		mMediaSource->setVolume(mRequestedVolume * LLViewerMedia::getVolume());
+		F32 attenuation_multiplier = 1.0;
+
+		if (mProximityDistance > 0)
+		{
+			// the attenuation multiplier should never be more than one since that would increase volume
+			attenuation_multiplier = llmin(1.0, gSavedSettings.getF32("MediaRollOffFactor")/mProximityDistance);
+		}
+
+		mMediaSource->setVolume(mRequestedVolume * LLViewerMedia::getVolume() * attenuation_multiplier);
 	}
 }
 
@@ -2427,6 +2435,8 @@ void LLViewerMediaImpl::update()
 	}
 	else
 	{
+		updateVolume();
+
 		// If we didn't just create the impl, it may need to get cookie updates.
 		if(!sUpdatedCookies.empty())
 		{
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 3d110dcc786c9b456a049d6c7243f4a1b84a646a..b8fab63be930a96f0f7666d229f1e501a1d16afa 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -60,6 +60,158 @@ bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,
 	return FALSE;
 }
 
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+void LLPanelWearableListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	LLPanelInventoryListItemBase::onMouseEnter(x, y, mask);
+	setWidgetsVisible(true);
+	reshapeWidgets();
+}
+
+void LLPanelWearableListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	LLPanelInventoryListItemBase::onMouseLeave(x, y, mask);
+	setWidgetsVisible(false);
+	reshapeWidgets();
+}
+
+LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item)
+: LLPanelInventoryListItemBase(item)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// static
+LLPanelClothingListItem* LLPanelClothingListItem::create(LLViewerInventoryItem* item)
+{
+	LLPanelClothingListItem* list_item = NULL;
+	if(item)
+	{
+		list_item = new LLPanelClothingListItem(item);
+		list_item->init();
+	}
+	return list_item;
+}
+
+LLPanelClothingListItem::LLPanelClothingListItem(LLViewerInventoryItem* item)
+ : LLPanelWearableListItem(item)
+{
+}
+
+LLPanelClothingListItem::~LLPanelClothingListItem()
+{
+}
+
+void LLPanelClothingListItem::init()
+{
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_clothing_list_item.xml");
+}
+
+BOOL LLPanelClothingListItem::postBuild()
+{
+	LLPanelInventoryListItemBase::postBuild();
+
+	addWidgetToLeftSide("btn_delete");
+	addWidgetToRightSide("btn_move_up");
+	addWidgetToRightSide("btn_move_down");
+	addWidgetToRightSide("btn_lock");
+	addWidgetToRightSide("btn_edit");
+
+	LLButton* delete_btn = getChild<LLButton>("btn_delete");
+	// Reserve space for 'delete' button event if it is invisible.
+	setLeftWidgetsWidth(delete_btn->getRect().mRight);
+
+	setWidgetsVisible(false);
+	reshapeWidgets();
+
+	return TRUE;
+}
+
+void LLPanelClothingListItem::setShowDeleteButton(bool show)
+{
+	setShowWidget("btn_delete", show);
+}
+
+void LLPanelClothingListItem::setShowMoveUpButton(bool show)
+{
+	setShowWidget("btn_move_up", show);
+}
+
+void LLPanelClothingListItem::setShowMoveDownButton(bool show)
+{
+	setShowWidget("btn_move_down", show);
+}
+
+void LLPanelClothingListItem::setShowLockButton(bool show)
+{
+	setShowWidget("btn_lock", show);
+}
+
+void LLPanelClothingListItem::setShowEditButton(bool show)
+{
+	setShowWidget("btn_edit", show);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// static
+LLPanelBodyPartsListItem* LLPanelBodyPartsListItem::create(LLViewerInventoryItem* item)
+{
+	LLPanelBodyPartsListItem* list_item = NULL;
+	if(item)
+	{
+		list_item = new LLPanelBodyPartsListItem(item);
+		list_item->init();
+	}
+	return list_item;
+}
+
+LLPanelBodyPartsListItem::LLPanelBodyPartsListItem(LLViewerInventoryItem* item)
+: LLPanelWearableListItem(item)
+{
+}
+
+LLPanelBodyPartsListItem::~LLPanelBodyPartsListItem()
+{
+}
+
+void LLPanelBodyPartsListItem::init()
+{
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_body_parts_list_item.xml");
+}
+
+BOOL LLPanelBodyPartsListItem::postBuild()
+{
+	LLPanelInventoryListItemBase::postBuild();
+
+	addWidgetToRightSide("btn_lock");
+	addWidgetToRightSide("btn_edit");
+
+	return TRUE;
+}
+
+void LLPanelBodyPartsListItem::setShowLockButton(bool show)
+{
+	setShowWidget("btn_lock", show);
+}
+
+void LLPanelBodyPartsListItem::setShowEditButton(bool show)
+{
+	setShowWidget("btn_edit", show);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
 static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
 
 LLWearableItemsList::Params::Params()
@@ -89,3 +241,5 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
 
 	refreshList(item_array);
 }
+
+// EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index e7ccba8e6c151b1ee64f8adebcfce0fe94341b2a..ae43b3f67325f283a7280cfd72a47cd83c01fcc3 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -36,6 +36,89 @@
 
 // newview
 #include "llinventoryitemslist.h"
+#include "llinventorymodel.h"
+#include "llwearabledictionary.h"
+
+/**
+ * @class LLPanelWearableListItem
+ *
+ * Extends LLPanelInventoryListItemBase:
+ * - makes side widgets show on mouse_enter and hide on 
+ *   mouse_leave events.
+ * - provides callback for button clicks
+ */
+class LLPanelWearableListItem : public LLPanelInventoryListItemBase
+{
+	LOG_CLASS(LLPanelWearableListItem);
+public:
+
+	/**
+	* Shows buttons when mouse is over
+	*/
+	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+
+	/**
+	* Hides buttons when mouse is out
+	*/
+	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+protected:
+
+	LLPanelWearableListItem(LLViewerInventoryItem* item);
+};
+
+/**
+ * @class LLPanelClothingListItem
+ *
+ * Provides buttons for editing, moving, deleting a wearable.
+ */
+class LLPanelClothingListItem : public LLPanelWearableListItem
+{
+	LOG_CLASS(LLPanelClothingListItem);
+public:
+
+	static LLPanelClothingListItem* create(LLViewerInventoryItem* item);
+
+	virtual ~LLPanelClothingListItem();
+
+	/*virtual*/ void init();
+	/*virtual*/ BOOL postBuild();
+
+	/**
+	 * Make button visible during mouse over event.
+	 */
+	inline void setShowDeleteButton(bool show);
+	inline void setShowMoveUpButton(bool show);
+	inline void setShowMoveDownButton(bool show);
+	inline void setShowLockButton(bool show);
+	inline void setShowEditButton(bool show);
+
+protected:
+
+	LLPanelClothingListItem(LLViewerInventoryItem* item);
+};
+
+class LLPanelBodyPartsListItem : public LLPanelWearableListItem
+{
+	LOG_CLASS(LLPanelBodyPartsListItem);
+public:
+
+	static LLPanelBodyPartsListItem* create(LLViewerInventoryItem* item);
+
+	virtual ~LLPanelBodyPartsListItem();
+
+	/*virtual*/ void init();
+	/*virtual*/ BOOL postBuild();
+
+	/**
+	* Make button visible during mouse over event.
+	*/
+	inline void setShowLockButton(bool show);
+	inline void setShowEditButton(bool show);
+
+protected:
+	LLPanelBodyPartsListItem(LLViewerInventoryItem* item);
+};
 
 /**
  * @class LLWearableItemsList
diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..445f677c94af730c19c9459249eeb7ed9e4f270f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="wearable_item"
+ top="0"
+ width="380">
+    <icon
+     follows="top|right|left"
+     height="20"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     height="20"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     height="16"
+     follows="top|left"
+     image_name="Inv_Object"
+     layout="topleft"
+     left="0"
+     name="item_icon"
+     top="2"
+     width="16" />
+    <text
+     follows="left|right"
+     height="16"
+     layout="topleft"
+     left_pad="5"
+     allow_html="false"
+     use_ellipses="true"
+     name="item_name"
+     text_color="white"
+     top="4"
+     value="..."
+     width="359" />
+    <button 
+     name="btn_lock"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Lock2"
+     image_selected="Lock2"
+     top="0"
+     left_pad="3"
+     height="20"
+     width="20"
+     tab_stop="false" />
+    <button 
+     name="btn_edit"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Icon_Gear_Background"
+     image_selected="Icon_Gear_Background"
+     top="0"
+     left_pad="3"
+     height="20"
+     width="20"
+     tab_stop="false" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..386b3b2c4fe91cd052c5ecb2dd33dbd089e08f75
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="wearable_item"
+ top="0"
+ width="380">
+    <icon
+     follows="top|right|left"
+     height="20"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     height="20"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <button 
+     name="btn_delete"
+     layout="topleft"
+     follows="top|left"
+     image_unselected="Toast_CloseBtn"
+     image_selected="Toast_CloseBtn"
+     top="0"
+     left="0"
+     height="20"
+     width="20"
+     tab_stop="false" />
+    <icon
+     height="16"
+     follows="top|left"
+     image_name="Inv_Object"
+     layout="topleft"
+     left_pad="3"
+     name="item_icon"
+     top="2"
+     width="16" />
+    <text
+     follows="left|right"
+     height="16"
+     layout="topleft"
+     left_pad="5"
+     allow_html="false"
+     use_ellipses="true"
+     name="item_name"
+     text_color="white"
+     top="4"
+     value="..."
+     width="359" />
+    <button 
+     name="btn_move_up"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Movement_Up_Off"
+     image_selected="Movement_Up_Off"
+     top="0"
+     left="0"
+     height="20"
+     width="20"
+     tab_stop="false" />
+    <button 
+     name="btn_move_down"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Movement_Down_Off"
+     image_selected="Movement_Down_Off"
+     top="0"
+     left_pad="3"
+     height="20"
+     width="20"
+     tab_stop="false" />
+    <button 
+     name="btn_lock"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Lock2"
+     image_selected="Lock2"
+     top="0"
+     left_pad="3"
+     height="20"
+     width="20"
+     tab_stop="false" />
+    <button 
+     name="btn_edit"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Icon_Gear_Background"
+     image_selected="Icon_Gear_Background"
+     top="0"
+     left_pad="3"
+     height="20"
+     width="20"
+     tab_stop="false" />
+</panel>
diff --git a/indra/newview/skins/default/xui/it/menu_participant_list.xml b/indra/newview/skins/default/xui/it/menu_participant_list.xml
index e641d3850837557ca2c91d05dd0c0c17132bcc73..0da1d116b445e88dffb9489fe3b123d732c25495 100644
--- a/indra/newview/skins/default/xui/it/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/it/menu_participant_list.xml
@@ -15,6 +15,6 @@
 		<menu_item_call label="Disattiva audio di questo participante" name="ModerateVoiceMuteSelected"/>
 		<menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceMuteOthers"/>
 		<menu_item_call label="Riattiva audio di questo participante" name="ModerateVoiceUnMuteSelected"/>
-		<menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/>
+		<menu_item_call label="Riattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/>
 	</context_menu>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 6736c6a6f13dbfafce41d700f8c1070688291654..f1b87bc002f3bfb2dc201ecd3db410ce76b9ed2e 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -898,7 +898,7 @@ Unisci il terreno?
 In genere si tratta di un problema temporaneo. Attendi alcuni minuti per modificare e salvare nuovamente gli elementi indossabili.
 	</notification>
 	<notification name="YouHaveBeenLoggedOut">
-		Accidenti. Sei stato scollegato da [SECOND_LIFE]
+		Sei stato scollegato da [SECOND_LIFE].
             [MESSAGE]
 		<usetemplate name="okcancelbuttons" notext="Esci" yestext="Vedi IM &amp; Chat"/>
 	</notification>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_pick.xml b/indra/newview/skins/default/xui/it/panel_edit_pick.xml
index d2d97cfc718c72cfd54f3cd38cdb3825c0f5c891..f93b953eac23d78c081113bf7f10ec1fe34c135c 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_pick.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Modifica scelta" name="panel_edit_pick">
+<panel label="Modifica preferito" name="panel_edit_pick">
 	<panel.string name="location_notice">
 		(si aggiornerà dopo il salvataggio)
 	</panel.string>
 	<text name="title">
-		Modifica scelta
+		Modifica preferito
 	</text>
 	<scroll_container name="profile_scroll">
 		<panel name="scroll_content_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
index c24d3f656a9d0e8bfa799f3181c0fad689a211bc..1d05f28d46a49803320e5cf0ffc33e370fd643b2 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
@@ -13,10 +13,10 @@
 	</text>
 	<check_box label="Costruire/Modificare" name="edit_camera_movement" tool_tip="Utilizza il posizionamento automatico della fotocamera entrando o uscendo dalla modalità modifica"/>
 	<check_box label="Aspetto fisico" name="appearance_camera_movement" tool_tip="Utilizza il posizionamento automatico della camera in modalità modifica"/>
-	<check_box label="Mostra in modalità Mouselook" name="first_person_avatar_visible"/>
+	<check_box label="Visualizzami in modalità soggettiva" name="first_person_avatar_visible"/>
 	<check_box label="Le frecce di direzione mi fanno sempre spostare" name="arrow_keys_move_avatar_check"/>
 	<check_box label="Doppio click e tieni premuto per correre" name="tap_tap_hold_to_run"/>
-	<check_box label="Consente il movimento delle labbra dell&apos;avatar quando parla" name="enable_lip_sync"/>
+	<check_box label="Movimento delle labbra dell&apos;avatar quando parla" name="enable_lip_sync"/>
 	<check_box label="Chat a bolla" name="bubble_text_chat"/>
 	<slider label="Opacità" name="bubble_chat_opacity"/>
 	<color_swatch name="background" tool_tip="Scegli il colore delle vignette della chat"/>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index a1b570d7160ec64fe2c990c41f663b807ee68fdc..de9c5ba45b93ec3d21d2916afacda962876cb19b 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -886,13 +886,13 @@
 		Alto
 	</string>
 	<string name="LeaveMouselook">
-		Premi ESC per tornare in visulizzazione normale
+		Premi ESC per tornare in visualizzazione normale
 	</string>
 	<string name="InventoryNoMatchingItems">
 		Nessun oggetto corrispondente trovato in inventario.  Prova [secondlife:///app/search/groups &quot;Cerca&quot;].
 	</string>
 	<string name="FavoritesNoMatchingItems">
-		Trascina qui un punto di riferimento per aggiungerlo ai tuoi preferiti.
+		Trascina qui un punto di riferimento per aggiungerlo ai Preferiti.
 	</string>
 	<string name="InventoryNoTexture">
 		Non hai una copia di questa texture nel tuo inventario
@@ -1566,7 +1566,7 @@
 		(si aggiornerà dopo la pubblicazione)
 	</string>
 	<string name="NoPicksClassifiedsText">
-		Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante più qui sotto per creare un luogo preferito o un&apos;inserzione.
+		Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un&apos;inserzione.
 	</string>
 	<string name="NoAvatarPicksClassifiedsText">
 		L&apos;utente non ha luoghi preferiti né inserzioni
diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml
index c11d41f6b96c2d57989414168a83ff6d048a2e59..7a1046abd36992b698144a0c158a7986319f87ea 100644
--- a/indra/newview/skins/default/xui/it/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/it/teleport_strings.xml
@@ -66,7 +66,7 @@ Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE
 			Elaborazione della destinazione in corso...
 		</message>
 		<message name="contacting">
-			Contattando la nuova regione.
+			Contatto in corso con la nuova regione.
 		</message>
 		<message name="arriving">
 			In arrivo a destinazione...