diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 24811db3cb48d7c29697871f9cd65770e3cebb3e..c1b2d680beb3752f89133a350f3995b9a20d7499 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -260,6 +260,7 @@ set(viewer_SOURCE_FILES
     llinventoryfunctions.cpp
     llinventoryicon.cpp
     llinventoryitemslist.cpp
+    llinventorylistitem.cpp
     llinventorymodel.cpp
     llinventorymodelbackgroundfetch.cpp
     llinventoryobserver.cpp
@@ -783,6 +784,7 @@ set(viewer_HEADER_FILES
     llinventoryfunctions.h
     llinventoryicon.h
     llinventoryitemslist.h
+    llinventorylistitem.h
     llinventorymodel.h
     llinventorymodelbackgroundfetch.h
     llinventoryobserver.h
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 14de5442d69b9c94c8bc77e8cd98712f84f517a0..fbb37749171137908f327acaca65294cba67790c 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -3,8 +3,6 @@
  * @brief A list of inventory items represented by LLFlatListView.
  *
  * Class LLInventoryItemsList implements a flat list of inventory items.
- * Class LLPanelInventoryListItem displays inventory item as an element
- * of LLInventoryItemsList.
  *
  * $LicenseInfo:firstyear=2010&license=viewergpl$
  *
@@ -40,341 +38,12 @@
 // llcommon
 #include "llcommonutils.h"
 
-// llui
-#include "lliconctrl.h"
-#include "lltextutil.h"
+#include "lltrans.h"
 
 #include "llcallbacklist.h"
-#include "llinventoryfunctions.h"
+#include "llinventorylistitem.h"
 #include "llinventorymodel.h"
-#include "lltrans.h"
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-static const S32 WIDGET_SPACING = 3;
-
-LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
-{
-	LLPanelInventoryListItemBase* list_item = NULL;
-	if (item)
-	{
-		list_item = new LLPanelInventoryListItemBase(item);
-		list_item->init();
-	}
-	return list_item;
-}
-
-void LLPanelInventoryListItemBase::draw()
-{
-	if (getNeedsRefresh())
-	{
-		if (mItem)
-		{
-			updateItem(mItem->getName());
-		}
-		setNeedsRefresh(false);
-	}
-	LLPanel::draw();
-}
-
-// virtual
-void LLPanelInventoryListItemBase::updateItem(const std::string& name,
-											  const LLStyle::Params& input_params)
-{
-	setIconImage(mIconImage);
-	setTitle(name, mHighlightedText, input_params);
-}
-
-void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
-{
-	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
-	if(ctrl)
-	{
-		addWidgetToLeftSide(ctrl, show_widget);
-	}
-}
-
-void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
-{
-	mLeftSideWidgets.push_back(ctrl);
-	setShowWidget(ctrl, show_widget);
-}
-
-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()
-{
-	setIconCtrl(getChild<LLIconCtrl>("item_icon"));
-	setTitleCtrl(getChild<LLTextBox>("item_name"));
-
-	if (mItem)
-	{
-		mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
-		updateItem(mItem->getName());
-	}
-
-	setNeedsRefresh(true);
-
-	setWidgetsVisible(false);
-	reshapeWidgets();
-
-	return TRUE;
-}
-
-void LLPanelInventoryListItemBase::setValue(const LLSD& value)
-{
-	if (!value.isMap()) return;
-	if (!value.has("selected")) return;
-	childSetVisible("selected_icon", value["selected"]);
-}
-
-void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	childSetVisible("hovered_icon", true);
-	LLPanel::onMouseEnter(x, y, mask);
-}
-
-void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	childSetVisible("hovered_icon", false);
-	LLPanel::onMouseLeave(x, y, mask);
-}
-
-const std::string& LLPanelInventoryListItemBase::getItemName() const
-{
-	if (!mItem)
-	{
-		return LLStringUtil::null;
-	}
-	return mItem->getName();
-}
-
-LLAssetType::EType LLPanelInventoryListItemBase::getType() const
-{
-	if (!mItem)
-	{
-		return LLAssetType::AT_NONE;
-	}
-	return mItem->getType();
-}
-
-LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const
-{
-	if (!mItem)
-	{
-		return LLWearableType::WT_NONE;
-	}
-	return mItem->getWearableType();
-}
-
-const std::string& LLPanelInventoryListItemBase::getDescription() const
-{
-	if (!mItem)
-	{
-		return LLStringUtil::null;
-	}
-	return mItem->getDescription();
-}
-
-S32 LLPanelInventoryListItemBase::notify(const LLSD& info)
-{
-	S32 rv = 0;
-	if(info.has("match_filter"))
-	{
-		mHighlightedText = info["match_filter"].asString();
-
-		std::string test(mTitleCtrl->getText());
-		LLStringUtil::toUpper(test);
-
-		if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText))
-		{
-			rv = 0; // substring is found
-		}
-		else
-		{
-			rv = -1;
-		}
-
-		setNeedsRefresh(true);
-	}
-	else
-	{
-		rv = LLPanel::notify(info);
-	}
-	return rv;
-}
-
-LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
-: LLPanel()
-, mItem(item)
-, mIconCtrl(NULL)
-, mTitleCtrl(NULL)
-, mWidgetSpacing(WIDGET_SPACING)
-, mLeftWidgetsWidth(0)
-, mRightWidgetsWidth(0)
-, mNeedsRefresh(false)
-{
-}
-
-void LLPanelInventoryListItemBase::init()
-{
-	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
-}
-
-class WidgetVisibilityChanger
-{
-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;
-};
-
-void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
-{
-	std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
-	std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
-}
-
-void LLPanelInventoryListItemBase::reshapeWidgets()
-{
-	// disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
-	/*reshapeLeftWidgets();*/
-	reshapeRightWidgets();
-	reshapeMiddleWidgets();
-}
-
-void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
-{
-	if(image)
-	{
-		mIconImage = image; 
-		mIconCtrl->setImage(mIconImage);
-	}
-}
-
-void LLPanelInventoryListItemBase::setTitle(const std::string& title,
-											const std::string& highlit_text,
-											const LLStyle::Params& input_params)
-{
-	mTitleCtrl->setToolTip(title);
-
-	LLTextUtil::textboxSetHighlightedVal(
-		mTitleCtrl,
-		input_params,
-		title,
-		highlit_text);
-}
-
-BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask)
-{
-	LLRect text_box_rect = mTitleCtrl->getRect();
-	if (text_box_rect.pointInRect(x, y) &&
-		mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth())
-	{
-		return FALSE;
-	}
-	return LLPanel::handleToolTip(x, y, mask);
-}
-
-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(mIconCtrl->getRect());
-	icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, 
-		icon_rect.getWidth(), icon_rect.getHeight());
-	mIconCtrl->setShape(icon_rect);
-
-	S32 name_left = icon_rect.mRight + getWidgetSpacing();
-	S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
-	LLRect name_rect(mTitleCtrl->getRect());
-	name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
-	mTitleCtrl->setShape(name_rect);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
+#include "llviewerinventory.h"
 
 LLInventoryItemsList::Params::Params()
 {}
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 5dc0bfe3de6c10a6ed23255f1c93ea8b2b9fc5a9..71c7b6a675066f2d91a08d688e3ab7bcc7c75bc6 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -3,8 +3,6 @@
  * @brief A list of inventory items represented by LLFlatListView.
  *
  * Class LLInventoryItemsList implements a flat list of inventory items.
- * Class LLPanelInventoryListItem displays inventory item as an element
- * of LLInventoryItemsList.
  *
  * $LicenseInfo:firstyear=2010&license=viewergpl$
  *
@@ -38,189 +36,11 @@
 
 #include "lldarray.h"
 
-#include "llpanel.h"
-
 // newview
 #include "llflatlistview.h"
-#include "llviewerinventory.h"
 
-class LLIconCtrl;
-class LLTextBox;
 class LLViewerInventoryItem;
 
-/**
- * @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 LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
-
-	virtual void draw();
-
-	/**
-	 * Let item know it need to be refreshed in next draw()
-	 */
-	void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
-
-	bool getNeedsRefresh(){ return mNeedsRefresh; }
-
-	/**
-	 * 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);
-
-	/**
-	 * Handles filter request
-	 */
-	/*virtual*/ S32  notify(const LLSD& info);
-
-	 /* Highlights item */
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
-	/* Removes item highlight */
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-
-	/** Get the name of a corresponding inventory item */
-	const std::string& getItemName() const;
-
-	/** Get the asset type of a corresponding inventory item */
-	LLAssetType::EType getType() const;
-
-	/** Get the wearable type of a corresponding inventory item */
-	LLWearableType::EType getWearableType() const;
-
-	/** Get the description of a corresponding inventory item */
-	const std::string& getDescription() const;
-
-	/** Get the associated inventory item */
-	LLViewerInventoryItem* getItem() const { return mItem; }
-
-	virtual ~LLPanelInventoryListItemBase(){}
-
-protected:
-
-	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();
-
-	/**
-	 * Called after inventory item was updated, update panel widgets to reflect inventory changes.
-	 */
-	virtual void updateItem(const std::string& name,
-							const LLStyle::Params& input_params = LLStyle::Params());
-
-	/** setter for mIconCtrl */
-	void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; }
-	/** setter for MTitleCtrl */
-	void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; }
-
-	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();
-
-	/** set wearable type icon image */
-	void setIconImage(const LLUIImagePtr& image);
-
-	/** Set item title - inventory item name usually */
-	virtual void setTitle(const std::string& title,
-						  const std::string& highlit_text,
-						  const LLStyle::Params& input_params = LLStyle::Params());
-
-	/**
-	 * Show tool tip if item name text size > panel size
-	 */
-	virtual BOOL handleToolTip( S32 x, S32 y, MASK mask);
-
-	LLViewerInventoryItem* mItem;
-
-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();
-
-
-	LLIconCtrl*		mIconCtrl;
-	LLTextBox*		mTitleCtrl;
-
-	LLUIImagePtr	mIconImage;
-	std::string		mHighlightedText;
-
-	widget_array_t	mLeftSideWidgets;
-	widget_array_t	mRightSideWidgets;
-	S32				mWidgetSpacing;
-
-	S32				mLeftWidgetsWidth;
-	S32				mRightWidgetsWidth;
-	bool			mNeedsRefresh;
-};
-
-//////////////////////////////////////////////////////////////////////////
-
 class LLInventoryItemsList : public LLFlatListViewEx
 {
 public:
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..18b6de77e240eb3b9aba12c6f71ff13c8e732379
--- /dev/null
+++ b/indra/newview/llinventorylistitem.cpp
@@ -0,0 +1,388 @@
+/**
+ * @file llinventorylistitem.cpp
+ * @brief Inventory list item panel.
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinventorylistitem.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llviewerinventory.h"
+
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
+
+static const S32 WIDGET_SPACING = 3;
+
+LLPanelInventoryListItemBase::Params::Params()
+:	default_style("default_style"),
+	worn_style("worn_style")
+{};
+
+LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
+{
+	LLPanelInventoryListItemBase* list_item = NULL;
+	if (item)
+	{
+		list_item = new LLPanelInventoryListItemBase(item);
+		list_item->init();
+	}
+	return list_item;
+}
+
+void LLPanelInventoryListItemBase::draw()
+{
+	if (getNeedsRefresh())
+	{
+		if (mItem)
+		{
+			updateItem(mItem->getName());
+		}
+		setNeedsRefresh(false);
+	}
+	LLPanel::draw();
+}
+
+// virtual
+void LLPanelInventoryListItemBase::updateItem(const std::string& name,
+											  EItemState item_state)
+{
+	setIconImage(mIconImage);
+	setTitle(name, mHighlightedText, item_state);
+}
+
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
+{
+	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
+	if(ctrl)
+	{
+		addWidgetToLeftSide(ctrl, show_widget);
+	}
+}
+
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
+{
+	mLeftSideWidgets.push_back(ctrl);
+	setShowWidget(ctrl, show_widget);
+}
+
+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()
+{
+	setIconCtrl(getChild<LLIconCtrl>("item_icon"));
+	setTitleCtrl(getChild<LLTextBox>("item_name"));
+
+	if (mItem)
+	{
+		mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
+		updateItem(mItem->getName());
+	}
+
+	setNeedsRefresh(true);
+
+	setWidgetsVisible(false);
+	reshapeWidgets();
+
+	return TRUE;
+}
+
+void LLPanelInventoryListItemBase::setValue(const LLSD& value)
+{
+	if (!value.isMap()) return;
+	if (!value.has("selected")) return;
+	childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	childSetVisible("hovered_icon", true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	childSetVisible("hovered_icon", false);
+	LLPanel::onMouseLeave(x, y, mask);
+}
+
+const std::string& LLPanelInventoryListItemBase::getItemName() const
+{
+	if (!mItem)
+	{
+		return LLStringUtil::null;
+	}
+	return mItem->getName();
+}
+
+LLAssetType::EType LLPanelInventoryListItemBase::getType() const
+{
+	if (!mItem)
+	{
+		return LLAssetType::AT_NONE;
+	}
+	return mItem->getType();
+}
+
+LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const
+{
+	if (!mItem)
+	{
+		return LLWearableType::WT_NONE;
+	}
+	return mItem->getWearableType();
+}
+
+const std::string& LLPanelInventoryListItemBase::getDescription() const
+{
+	if (!mItem)
+	{
+		return LLStringUtil::null;
+	}
+	return mItem->getDescription();
+}
+
+S32 LLPanelInventoryListItemBase::notify(const LLSD& info)
+{
+	S32 rv = 0;
+	if(info.has("match_filter"))
+	{
+		mHighlightedText = info["match_filter"].asString();
+
+		std::string test(mTitleCtrl->getText());
+		LLStringUtil::toUpper(test);
+
+		if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText))
+		{
+			rv = 0; // substring is found
+		}
+		else
+		{
+			rv = -1;
+		}
+
+		setNeedsRefresh(true);
+	}
+	else
+	{
+		rv = LLPanel::notify(info);
+	}
+	return rv;
+}
+
+LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
+: LLPanel()
+, mItem(item)
+, mIconCtrl(NULL)
+, mTitleCtrl(NULL)
+, mWidgetSpacing(WIDGET_SPACING)
+, mLeftWidgetsWidth(0)
+, mRightWidgetsWidth(0)
+, mNeedsRefresh(false)
+{
+}
+
+void LLPanelInventoryListItemBase::init()
+{
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
+}
+
+class WidgetVisibilityChanger
+{
+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;
+};
+
+void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
+{
+	std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
+	std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
+}
+
+void LLPanelInventoryListItemBase::reshapeWidgets()
+{
+	// disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
+	/*reshapeLeftWidgets();*/
+	reshapeRightWidgets();
+	reshapeMiddleWidgets();
+}
+
+void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
+{
+	if(image)
+	{
+		mIconImage = image; 
+		mIconCtrl->setImage(mIconImage);
+	}
+}
+
+void LLPanelInventoryListItemBase::setTitle(const std::string& title,
+											const std::string& highlit_text,
+											EItemState item_state)
+{
+	mTitleCtrl->setToolTip(title);
+
+	LLStyle::Params style_params;
+
+	const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>();
+
+	switch(item_state)
+	{
+	case IS_DEFAULT:
+		style_params = params.default_style();
+		break;
+	case IS_WORN:
+		style_params = params.worn_style();
+		break;
+	default:;
+	}
+
+	LLTextUtil::textboxSetHighlightedVal(
+		mTitleCtrl,
+		style_params,
+		title,
+		highlit_text);
+}
+
+BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask)
+{
+	LLRect text_box_rect = mTitleCtrl->getRect();
+	if (text_box_rect.pointInRect(x, y) &&
+		mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth())
+	{
+		return FALSE;
+	}
+	return LLPanel::handleToolTip(x, y, mask);
+}
+
+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(mIconCtrl->getRect());
+	icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, 
+		icon_rect.getWidth(), icon_rect.getHeight());
+	mIconCtrl->setShape(icon_rect);
+
+	S32 name_left = icon_rect.mRight + getWidgetSpacing();
+	S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
+	LLRect name_rect(mTitleCtrl->getRect());
+	name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
+	mTitleCtrl->setShape(name_rect);
+}
+
+// EOF
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..599431af3fb0480ff90d6f2bd6f97636e9dfcd8f
--- /dev/null
+++ b/indra/newview/llinventorylistitem.h
@@ -0,0 +1,235 @@
+/**
+ * @file llinventorylistitem.h
+ * @brief Inventory list item panel.
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYLISTITEM_H
+#define LL_LLINVENTORYLISTITEM_H
+
+// llcommon
+#include "llassettype.h"
+
+// llui
+#include "llpanel.h"
+#include "llstyle.h"
+
+// newview
+#include "llwearabletype.h"
+
+class LLIconCtrl;
+class LLTextBox;
+class LLViewerInventoryItem;
+
+/**
+ * @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:
+	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+	{
+		Optional<LLStyle::Params>	default_style,
+									worn_style;
+		Params();
+	};
+
+	typedef enum e_item_state {
+		IS_DEFAULT,
+		IS_WORN,
+	} EItemState;
+
+	static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
+
+	virtual void draw();
+
+	/**
+	 * Let item know it need to be refreshed in next draw()
+	 */
+	void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
+
+	bool getNeedsRefresh(){ return mNeedsRefresh; }
+
+	/**
+	 * 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);
+
+	/**
+	 * Handles filter request
+	 */
+	/*virtual*/ S32  notify(const LLSD& info);
+
+	 /* Highlights item */
+	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+	/* Removes item highlight */
+	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	/** Get the name of a corresponding inventory item */
+	const std::string& getItemName() const;
+
+	/** Get the asset type of a corresponding inventory item */
+	LLAssetType::EType getType() const;
+
+	/** Get the wearable type of a corresponding inventory item */
+	LLWearableType::EType getWearableType() const;
+
+	/** Get the description of a corresponding inventory item */
+	const std::string& getDescription() const;
+
+	/** Get the associated inventory item */
+	LLViewerInventoryItem* getItem() const { return mItem; }
+
+	virtual ~LLPanelInventoryListItemBase(){}
+
+protected:
+
+	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();
+
+	/**
+	 * Called after inventory item was updated, update panel widgets to reflect inventory changes.
+	 */
+	virtual void updateItem(const std::string& name,
+							EItemState item_state = IS_DEFAULT);
+
+	/** setter for mIconCtrl */
+	void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; }
+	/** setter for MTitleCtrl */
+	void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; }
+
+	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();
+
+	/** set wearable type icon image */
+	void setIconImage(const LLUIImagePtr& image);
+
+	/** Set item title - inventory item name usually */
+	void setTitle(const std::string& title,
+				  const std::string& highlit_text,
+				  EItemState item_state = IS_DEFAULT);
+
+	/**
+	 * Show tool tip if item name text size > panel size
+	 */
+	virtual BOOL handleToolTip( S32 x, S32 y, MASK mask);
+
+	LLViewerInventoryItem* mItem;
+
+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();
+
+
+	LLIconCtrl*		mIconCtrl;
+	LLTextBox*		mTitleCtrl;
+
+	LLUIImagePtr	mIconImage;
+	std::string		mHighlightedText;
+
+	widget_array_t	mLeftSideWidgets;
+	widget_array_t	mRightSideWidgets;
+	S32				mWidgetSpacing;
+
+	S32				mLeftWidgetsWidth;
+	S32				mRightWidgetsWidth;
+	bool			mNeedsRefresh;
+};
+
+#endif //LL_LLINVENTORYLISTITEM_H
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 9c308359fa92f6b9cc096c80c5b8b8355af5ac8f..427a0dc34d4bab351f0cce759085dd2c7b7b1799 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,11 +34,11 @@
 #include "llwearableitemslist.h"
 
 #include "lliconctrl.h"
+#include "llmenugl.h" // for LLContextMenu
 
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llinventoryfunctions.h"
-#include "llmenugl.h" // for LLContextMenu
 #include "lltransutil.h"
 #include "llviewerattachmenu.h"
 #include "llvoavatarself.h"
@@ -113,18 +113,17 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item
 
 // virtual
 void LLPanelWearableOutfitItem::updateItem(const std::string& name,
-										   const LLStyle::Params& input_params)
+										   EItemState item_state)
 {
 	std::string search_label = name;
-	LLStyle::Params style_params = input_params;
 
 	if (mItem && get_is_item_worn(mItem->getUUID()))
 	{
 		search_label += LLTrans::getString("worn");
-		style_params.font.style("BOLD");
+		item_state = IS_WORN;
 	}
 
-	LLPanelInventoryListItemBase::updateItem(search_label, style_params);
+	LLPanelInventoryListItemBase::updateItem(search_label, item_state);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -264,19 +263,18 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt
 	return list_item;
 }
 
-void LLPanelAttachmentListItem::setTitle(const std::string& title,
-										 const std::string& highlit_text,
-										 const LLStyle::Params& input_params)
+void LLPanelAttachmentListItem::updateItem(const std::string& name,
+										   EItemState item_state)
 {
-	std::string title_joint = title;
+	std::string title_joint;
 
 	if (mItem && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(mItem->getLinkedUUID()))
 	{
 		std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(mItem->getLinkedUUID()));
-		title_joint = title + " (" + joint + ")";
+		title_joint = name + " (" + joint + ")";
 	}
 
-	LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text, input_params);
+	LLPanelInventoryListItemBase::updateItem(title_joint, item_state);
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 5dc06284c387b2582c68c6c24de3513d5c30a7ce..2bfb90e3ec506101da22eab60159a60f747cebf9 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -38,6 +38,7 @@
 
 // newview
 #include "llinventoryitemslist.h"
+#include "llinventorylistitem.h"
 #include "llinventorymodel.h"
 #include "lllistcontextmenu.h"
 #include "llwearabletype.h"
@@ -87,7 +88,7 @@ class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase
 	 * Updates item name and (worn) suffix.
 	 */
 	/*virtual*/ void updateItem(const std::string& name,
-								const LLStyle::Params& input_params = LLStyle::Params());
+								EItemState item_state = IS_DEFAULT);
 
 protected:
 	LLPanelWearableOutfitItem(LLViewerInventoryItem* item);
@@ -124,9 +125,8 @@ class LLPanelAttachmentListItem : public LLPanelDeletableWearableListItem
 	virtual ~LLPanelAttachmentListItem() {};
 
 	/** Set item title. Joint name is added to the title in parenthesis */
-	/*virtual*/ void setTitle(const std::string& title,
-							  const std::string& highlit_text,
-							  const LLStyle::Params& input_params = LLStyle::Params());
+	/*virtual*/ void updateItem(const std::string& name,
+								EItemState item_state = IS_DEFAULT);
 
 protected:
 	LLPanelAttachmentListItem(LLViewerInventoryItem* item) : LLPanelDeletableWearableListItem(item) {};
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dbe1ea2874134d07a23cfdf7dcd821d6603813d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<inventory_list_item
+ height="0"
+ layout="topleft"
+ left="0"
+ name="inventory_list_item"
+ top="0"
+ width="0">
+  <!-- DEFAULT style for inventory list item -->
+  <default_style
+   font="SansSerifSmall"
+   font.style="NORMAL" />
+
+  <!-- style for inventory list item WORN on avatar -->
+  <worn_style
+   font="SansSerifSmall"
+   font.style="BOLD" />
+</inventory_list_item>