From 7df79382a075646a51f21bed0d7f8de883fc3608 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Fri, 11 Sep 2009 23:50:59 +0000
Subject: [PATCH] merge
 https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1634
 https://svn.aws.productengine.com/secondlife/pe/stable-2@1648 ->
 viewer-2.0.0-3 * Bugs: EXT-888 EXT-866 EXT-861 EXT-858 EXT-864 EXT-875
 EXT-884 EXT-718 EXT-786 EXT-885 EXT-910 EXT-845 EXT-312 EXT-823 EXT-868 * New
 Development: EXT-748 EXT-863 EXT-835

QA: Please test Recent List to verify it has no troubles.
---
 indra/llcommon/llstring.cpp                   |   9 +-
 indra/llui/CMakeLists.txt                     |   2 +
 indra/llui/lldockcontrol.cpp                  |  13 +
 indra/llui/lldockcontrol.h                    |   3 +-
 indra/llui/llfiltereditor.cpp                 |  74 +--
 indra/llui/llfiltereditor.h                   |  30 +-
 indra/llui/llflatlistview.cpp                 | 494 ++++++++++++++++++
 indra/llui/llflatlistview.h                   | 262 ++++++++++
 indra/llui/llsearcheditor.cpp                 |  82 ++-
 indra/llui/llsearcheditor.h                   |  24 +-
 indra/llui/lltabcontainer.cpp                 |   9 +-
 indra/llui/llview.h                           |   2 +-
 indra/newview/llavatarlist.cpp                | 213 ++++++++
 indra/newview/llavatarlist.h                  |  42 ++
 indra/newview/llavatarlistitem.cpp            | 221 ++------
 indra/newview/llavatarlistitem.h              |  94 ++--
 indra/newview/llchiclet.cpp                   |  26 +-
 indra/newview/llchiclet.h                     |   1 -
 indra/newview/llfloatercamera.cpp             |  18 +-
 indra/newview/llfloatercamera.h               |   5 +-
 indra/newview/llimhandler.cpp                 |   9 +-
 indra/newview/llimview.cpp                    |   3 +-
 indra/newview/llnearbychatbar.cpp             |  20 +-
 indra/newview/llnearbychatbar.h               |   1 +
 indra/newview/lloutputmonitorctrl.cpp         |  48 +-
 indra/newview/lloutputmonitorctrl.h           |  18 +-
 indra/newview/llpanelavatar.cpp               |   2 +-
 indra/newview/llpanelgrouproles.cpp           |  28 +-
 indra/newview/llpanelgrouproles.h             |   9 +-
 indra/newview/llpanelpeople.cpp               |  19 +-
 indra/newview/llpanelpeople.h                 |   3 +-
 indra/newview/llpanelplaceinfo.cpp            | 122 ++---
 indra/newview/llpanelplaceinfo.h              |  21 +-
 indra/newview/llpanelplaces.cpp               | 159 ++++--
 indra/newview/llpanelplaces.h                 |  31 +-
 indra/newview/llrecentpeople.cpp              |   7 +-
 indra/newview/llrecentpeople.h                |   7 +-
 indra/newview/llsearchcombobox.cpp            |   1 +
 indra/newview/lltoastimpanel.cpp              |   5 +-
 indra/newview/lltoastimpanel.h                |   1 +
 indra/newview/llviewermenu.cpp                |   4 +-
 indra/newview/llviewerwindow.cpp              |   2 +-
 .../default/xui/en/floater_inventory.xml      |   2 +
 .../skins/default/xui/en/floater_sys_well.xml |   3 -
 .../default/xui/en/panel_avatar_list_item.xml | 152 +++---
 .../default/xui/en/panel_group_roles.xml      |  38 +-
 .../skins/default/xui/en/panel_people.xml     |  17 +-
 .../skins/default/xui/en/panel_places.xml     |  15 -
 .../skins/default/xui/en/panel_toast.xml      |   4 +-
 .../newview/skins/default/xui/en/strings.xml  |   1 +
 .../default/xui/en/widgets/filter_editor.xml  |  24 +-
 .../default/xui/en/widgets/flat_list_view.xml |   7 +
 .../default/xui/en/widgets/search_editor.xml  |   3 +-
 53 files changed, 1694 insertions(+), 716 deletions(-)
 create mode 100644 indra/llui/llflatlistview.cpp
 create mode 100644 indra/llui/llflatlistview.h
 create mode 100644 indra/newview/skins/default/xui/en/widgets/flat_list_view.xml

diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 78e835dc95f..8052da24505 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -968,8 +968,13 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
 
 	// special case to handle timezone
 	if (code == "%Z") {
-		if (param == "utc") replacement = "GMT";
-		else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST";
+		if (param == "utc")
+			replacement = "GMT";
+		else if (param == "slt")
+			replacement = "SLT";
+		else if (param != "local") // *TODO Vadim: not local? then what?
+			replacement = LLStringOps::getDaylightSavings() ? "PDT" : "PST";
+
 		return true;
 	}
 	replacement = datetime->toHTTPDateString(code);
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index cc9362a2525..fce6b759a45 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -40,6 +40,7 @@ set(llui_SOURCE_FILES
     lleditmenuhandler.cpp
     llf32uictrl.cpp
     llfiltereditor.cpp
+    llflatlistview.cpp
     llfloater.cpp
     llfloaterreg.cpp
     llflyoutbutton.cpp 
@@ -122,6 +123,7 @@ set(llui_HEADER_FILES
     lleditmenuhandler.h
     llf32uictrl.h
     llfiltereditor.h 
+    llflatlistview.h
     llfloater.h
     llfloaterreg.h
     llflyoutbutton.h 
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index e119d387ce4..d666f2be56e 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -48,12 +48,25 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 	{
 		off();
 	}
+
+	if (dockWidget != NULL) {
+		repositionDockable();
+	}
 }
 
 LLDockControl::~LLDockControl()
 {
 }
 
+void LLDockControl::setDock(LLView* dockWidget)
+{
+	mDockWidget = dockWidget;
+	if (mDockWidget != NULL)
+	{
+		repositionDockable();
+	}
+}
+
 void LLDockControl::repositionDockable()
 {
 	if (mEnabled)
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index ae4e53ddc9f..7d8d5c76537 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -60,8 +60,7 @@ class LLDockControl
 public:
 	void on();
 	void off();
-	void setDock(LLView* dockWidget)
-	{	mDockWidget = dockWidget;};
+	void setDock(LLView* dockWidget);
 	void repositionDockable();
 	void drawToungue();
 protected:
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
index 26b5f2e182b..390504234d4 100644
--- a/indra/llui/llfiltereditor.cpp
+++ b/indra/llui/llfiltereditor.cpp
@@ -37,81 +37,15 @@
 #include "llfiltereditor.h"
 
 LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
-:	LLUICtrl(p)
+:	LLSearchEditor(p)
 {
-	LLLineEditor::Params line_editor_p(p);
-	line_editor_p.name("filter edit box");
-	line_editor_p.rect(getLocalRect());
-	line_editor_p.follows.flags(FOLLOWS_ALL);
-	line_editor_p.text_pad_right(getRect().getHeight());
-	line_editor_p.revert_on_esc(false);
-	line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this));
-
-	mFilterEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
-	addChild(mFilterEditor);
-
-	S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor
-	LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0);
-	LLButton::Params button_params(p.clear_filter_button);
-	button_params.name(std::string("clear filter"));
-	button_params.rect(clear_btn_rect) ;
-	button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
-	button_params.tab_stop(false);
-	button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2));
-
-	mClearFilterButton = LLUICtrlFactory::create<LLButton>(button_params);
-	mFilterEditor->addChild(mClearFilterButton);
-}
-
-//virtual
-void LLFilterEditor::setValue(const LLSD& value )
-{
-	mFilterEditor->setValue(value);
-}
-
-//virtual
-LLSD LLFilterEditor::getValue() const
-{
-	return mFilterEditor->getValue();
-}
-
-//virtual
-BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
-{
-	return mFilterEditor->setTextArg(key, text);
 }
 
-//virtual
-BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
-{
-	return mFilterEditor->setLabelArg(key, text);
-}
-
-//virtual
-void LLFilterEditor::setLabel( const LLStringExplicit &new_label )
-{
-	mFilterEditor->setLabel(new_label);
-}
-
-//virtual
-void LLFilterEditor::clear()
-{
-	if (mFilterEditor)
-	{
-		mFilterEditor->clear();
-	}
-}
 
-void LLFilterEditor::draw()
+void LLFilterEditor::handleKeystroke()
 {
-	mClearFilterButton->setVisible(!mFilterEditor->getWText().empty());
-
-	LLUICtrl::draw();
-}
+	this->LLSearchEditor::handleKeystroke();
 
-void LLFilterEditor::onClearFilter(const LLSD& data)
-{
-	setText(LLStringUtil::null);
+	// Commit on every keystroke.
 	onCommit();
 }
-
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
index fceb82af8da..c43a76b1305 100644
--- a/indra/llui/llfiltereditor.h
+++ b/indra/llui/llfiltereditor.h
@@ -42,18 +42,14 @@
 #ifndef LL_FILTEREDITOR_H
 #define LL_FILTEREDITOR_H
 
-#include "lllineeditor.h"
-#include "llbutton.h"
+#include "llsearcheditor.h"
 
-class LLFilterEditor : public LLUICtrl
+class LLFilterEditor : public LLSearchEditor
 {
 public:
-	struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+	struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params>
 	{
-		Optional<LLButton::Params> clear_filter_button;
-
 		Params()
-		: clear_filter_button("clear_filter_button")
 		{
 			name = "filter_editor";
 		}
@@ -62,26 +58,8 @@ class LLFilterEditor : public LLUICtrl
 protected:
 	LLFilterEditor(const Params&);
 	friend class LLUICtrlFactory;
-public:
-	virtual ~LLFilterEditor() {}
-
-	/*virtual*/ void	draw();
-
-	void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); }
-
-	// LLUICtrl interface
-	virtual void	setValue(const LLSD& value );
-	virtual LLSD	getValue() const;
-	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
-	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
-	virtual void	setLabel( const LLStringExplicit &new_label );
-	virtual void	clear();
-
-private:
-	void onClearFilter(const LLSD& data);
 
-	LLLineEditor* mFilterEditor;
-	LLButton* mClearFilterButton;
+	/*virtual*/ void handleKeystroke();
 };
 
 #endif  // LL_FILTEREDITOR_H
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
new file mode 100644
index 00000000000..75334acb399
--- /dev/null
+++ b/indra/llui/llflatlistview.cpp
@@ -0,0 +1,494 @@
+/** 
+ * @file llflatlistview.cpp
+ * @brief LLFlatListView base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, 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 "linden_common.h"
+
+#include "llpanel.h"
+
+#include "llflatlistview.h"
+
+static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
+
+const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+
+LLFlatListView::Params::Params()
+:	item_pad("item_pad"),
+	allow_select("allow_select"),
+	multi_select("multi_select"),
+	keep_one_selected("keep_one_selected")
+{};
+
+void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
+{
+	LLScrollContainer::reshape(width, height, called_from_parent);
+	setItemsNoScrollWidth(width);
+	rearrangeItems();
+}
+
+bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
+{
+	if (!item) return false;
+	if (value.isUndefined()) return false;
+	
+	//force uniqueness of items, easiest check but unreliable
+	if (item->getParent() == mItemsPanel) return false;
+	
+	item_pair_t* new_pair = new item_pair_t(item, value);
+	switch (pos)
+	{
+	case ADD_TOP:
+		mItemPairs.push_front(new_pair);
+		//in LLView::draw() children are iterated in backorder
+		mItemsPanel->addChildInBack(item);
+		break;
+	case ADD_BOTTOM:
+		mItemPairs.push_back(new_pair);
+		mItemsPanel->addChild(item);
+		break;
+	default:
+		break;
+	}
+	
+	//_4 is for MASK
+	item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+	item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+
+	rearrangeItems();
+	return true;
+}
+
+
+bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/)
+{
+	if (!after_item) return false;
+	if (!item_to_add) return false;
+	if (value.isUndefined()) return false;
+
+	if (mItemPairs.empty()) return false;
+
+	//force uniqueness of items, easiest check but unreliable
+	if (item_to_add->getParent() == mItemsPanel) return false;
+
+	item_pair_t* after_pair = getItemPair(after_item);
+	if (!after_pair) return false;
+
+	item_pair_t* new_pair = new item_pair_t(item_to_add, value);
+	if (after_pair == mItemPairs.back())
+	{
+		mItemPairs.push_back(new_pair);
+		mItemsPanel->addChild(item_to_add);
+	}
+	else
+	{
+		pairs_iterator_t it = mItemPairs.begin();
+		++it;
+		while (it != mItemPairs.end())
+		{
+			if (*it == after_pair)
+			{
+				mItemPairs.insert(++it, new_pair);
+				mItemsPanel->addChild(item_to_add);
+				break;
+			}
+		}
+	}
+
+	//_4 is for MASK
+	item_to_add->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+	item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
+
+	rearrangeItems();
+	return true;
+}
+
+
+bool LLFlatListView::removeItem(LLPanel* item)
+{
+	if (!item) return false;
+	if (item->getParent() != mItemsPanel) return false;
+	
+	item_pair_t* item_pair = getItemPair(item);
+	if (!item_pair) return false;
+
+	return removeItemPair(item_pair);
+}
+
+bool LLFlatListView::removeItemByValue(const LLSD& value)
+{
+	if (value.isUndefined()) return false;
+	
+	item_pair_t* item_pair = getItemPair(value);
+	if (!item_pair) return false;
+
+	return removeItemPair(item_pair);
+}
+
+bool LLFlatListView::removeItemByUUID(LLUUID& uuid)
+{
+	return removeItemByValue(LLSD(uuid));
+}
+
+LLPanel* LLFlatListView::getItemByValue(LLSD& value) const
+{
+	if (value.isDefined()) return NULL;
+
+	item_pair_t* pair = getItemPair(value);
+	if (pair) return pair->first;
+	return NULL;
+}
+
+bool LLFlatListView::selectItem(LLPanel* item, bool select /*= true*/)
+{
+	if (!item) return false;
+	if (item->getParent() != mItemsPanel) return false;
+	
+	item_pair_t* item_pair = getItemPair(item);
+	if (!item_pair) return false;
+
+	return selectItemPair(item_pair, select);
+}
+
+bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/)
+{
+	if (value.isUndefined()) return false;
+
+	item_pair_t* item_pair = getItemPair(value);
+	if (!item_pair) return false;
+
+	return selectItemPair(item_pair, select);
+}
+
+bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/)
+{
+	return selectItemByValue(LLSD(uuid), select);
+}
+
+
+LLSD LLFlatListView::getSelectedValue() const
+{
+	if (mSelectedItemPairs.empty()) return LLSD();
+
+	item_pair_t* first_selected_pair = mSelectedItemPairs.front();
+	return first_selected_pair->second;
+}
+
+void LLFlatListView::getSelectedValues(std::vector<LLSD>& selected_values) const
+{
+	if (mSelectedItemPairs.empty()) return;
+
+	for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+	{
+		selected_values.push_back((*it)->second);
+	}
+}
+
+LLUUID LLFlatListView::getSelectedUUID() const
+{
+	const LLSD& value = getSelectedValue();
+	if (value.isDefined() && value.isUUID())
+	{
+		return value.asUUID();
+	}
+	else 
+	{
+		return LLUUID::null;
+	}
+}
+
+void LLFlatListView::getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const
+{
+	if (mSelectedItemPairs.empty()) return;
+
+	for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+	{
+		selected_uuids.push_back((*it)->second.asUUID());
+	}
+}
+
+LLPanel* LLFlatListView::getSelectedItem() const
+{
+	if (mSelectedItemPairs.empty()) return NULL;
+
+	return mSelectedItemPairs.front()->first;
+}
+
+void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) const
+{
+	if (mSelectedItemPairs.empty()) return;
+
+	for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+	{
+		selected_items.push_back((*it)->first);
+	}
+}
+
+void LLFlatListView::resetSelection()
+{
+	if (mSelectedItemPairs.empty()) return;
+
+	for (pairs_iterator_t it= mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+	{
+		item_pair_t* pair_to_deselect = *it;
+		LLPanel* item = pair_to_deselect->first;
+		item->setValue(UNSELECTED_EVENT);
+	}
+
+	mSelectedItemPairs.clear();
+}
+
+void LLFlatListView::clear()
+{
+	// do not use LLView::deleteAllChildren to avoid removing nonvisible items. drag-n-drop for ex.
+	for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+	{
+		mItemsPanel->removeChild((*it)->first);
+		delete (*it)->first;
+		delete *it;
+	}
+	mItemPairs.clear();
+	mSelectedItemPairs.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED STUFF
+//////////////////////////////////////////////////////////////////////////
+
+
+LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
+:	LLScrollContainer(p),
+	mItemsPanel(NULL),
+	mItemPad(p.item_pad),
+	mAllowSelection(p.allow_select),
+	mMultipleSelection(p.multi_select),
+	mKeepOneItemSelected(p.keep_one_selected)
+{
+	mBorderThickness = getBorderWidth();
+
+	LLRect scroll_rect = getRect();
+	LLRect items_rect;
+
+	setItemsNoScrollWidth(scroll_rect.getWidth());
+	items_rect.setLeftTopAndSize(mBorderThickness, scroll_rect.getHeight() - mBorderThickness, mItemsNoScrollWidth, 0);
+
+	LLPanel::Params pp;
+	pp.rect(items_rect);
+	mItemsPanel = LLUICtrlFactory::create<LLPanel> (pp);
+	addChild(mItemsPanel);
+
+	//we don't need to stretch in vertical direction on reshaping by a parent
+	//no bottom following!
+	mItemsPanel->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
+};
+
+void LLFlatListView::rearrangeItems()
+{
+	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+	if (mItemPairs.empty()) return;
+
+	//calculating required height - assuming items can be of different height
+	//list should accommodate all its items
+	S32 height = 0;
+
+	pairs_iterator_t it = mItemPairs.begin();
+	for (; it != mItemPairs.end(); ++it)
+	{
+		LLPanel* item = (*it)->first;
+		height += item->getRect().getHeight();
+	}
+	height += mItemPad * (mItemPairs.size() - 1);
+
+	LLRect rc = mItemsPanel->getRect();
+	S32 width = mItemsNoScrollWidth;
+
+	// update width to avoid horizontal scrollbar
+	if (height > getRect().getHeight() - 2 * mBorderThickness)
+		width -= scrollbar_size;
+
+	//changes the bottom, end of the list goes down in the scroll container
+	rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height);
+	mItemsPanel->setRect(rc);
+
+	//reshaping items
+	S32 item_new_top = height;
+	pairs_iterator_t it2, first_it = mItemPairs.begin();
+	for (it2 = first_it; it2 != mItemPairs.end(); ++it2)
+	{
+		LLPanel* item = (*it2)->first;
+		LLRect rc = item->getRect();
+		if(it2 != first_it)
+		{
+			item_new_top -= (rc.getHeight() + mItemPad);
+		}
+		rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight());
+		item->reshape(rc.getWidth(), rc.getHeight());
+		item->setRect(rc);
+	}
+}
+
+void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
+{
+	if (!item_pair) return;
+	
+	bool select_item = !isSelected(item_pair);
+
+	//*TODO find a better place for that enforcing stuff
+	if (mKeepOneItemSelected && numSelected() == 1 && !select_item) return;
+	
+	if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection();
+	selectItemPair(item_pair, select_item);
+}
+
+LLFlatListView::item_pair_t* LLFlatListView::getItemPair(LLPanel* item) const
+{
+	llassert(item);
+
+	for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
+	{
+		item_pair_t* item_pair = *it;
+		if (item_pair->first == item) return item_pair;
+	}
+	return NULL;
+}
+
+//compares two LLSD's
+bool llsds_are_equal(const LLSD& llsd_1, const LLSD& llsd_2)
+{
+	llassert(llsd_1.isDefined());
+	llassert(llsd_2.isDefined());
+	
+	if (llsd_1.type() != llsd_2.type()) return false;
+
+	if (!llsd_1.isMap())
+	{
+		if (llsd_1.isUUID()) return llsd_1.asUUID() == llsd_2.asUUID();
+
+		//assumptions that string representaion is enough for other types
+		return llsd_1.asString() == llsd_2.asString();
+	}
+
+	if (llsd_1.size() != llsd_2.size()) return false;
+
+	LLSD::map_const_iterator llsd_1_it = llsd_1.beginMap();
+	LLSD::map_const_iterator llsd_2_it = llsd_2.beginMap();
+	for (S32 i = 0; i < llsd_1.size(); ++i)
+	{
+		if ((*llsd_1_it).first != (*llsd_2_it).first) return false;
+		if (!llsds_are_equal((*llsd_1_it).second, (*llsd_2_it).second)) return false;
+		++llsd_1_it;
+		++llsd_2_it;
+	}
+	return true;
+}
+
+LLFlatListView::item_pair_t* LLFlatListView::getItemPair(const LLSD& value) const
+{
+	llassert(value.isDefined());
+	
+	for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
+	{
+		item_pair_t* item_pair = *it;
+		if (llsds_are_equal(item_pair->second, value)) return item_pair;
+	}
+	return NULL;
+}
+
+bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
+{
+	llassert(item_pair);
+
+	if (!mAllowSelection && select) return false;
+
+	if (isSelected(item_pair) == select) return true; //already in specified selection state
+	if (select)
+	{
+		mSelectedItemPairs.push_back(item_pair);
+	}
+	else
+	{
+		mSelectedItemPairs.remove(item_pair);
+	}
+
+	//a way of notifying panel of selection state changes
+	LLPanel* item = item_pair->first;
+	item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT);
+	return true;
+}
+
+bool LLFlatListView::isSelected(item_pair_t* item_pair) const
+{
+	llassert(item_pair);
+
+	pairs_const_iterator_t it_end = mSelectedItemPairs.end();
+	return std::find(mSelectedItemPairs.begin(), it_end, item_pair) != it_end;
+}
+
+bool LLFlatListView::removeItemPair(item_pair_t* item_pair)
+{
+	llassert(item_pair);
+
+	bool deleted = false;
+	for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+	{
+		item_pair_t* _item_pair = *it;
+		if (_item_pair == item_pair)
+		{
+			mItemPairs.erase(it);
+			deleted = true;
+			break;
+		}
+	}
+
+	if (!deleted) return false;
+
+	for (pairs_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it)
+	{
+		item_pair_t* selected_item_pair = *it;
+		if (selected_item_pair == item_pair)
+		{
+			it = mSelectedItemPairs.erase(it);
+			break;
+		}
+	}
+
+	mItemsPanel->removeChild(item_pair->first);
+	delete item_pair->first;
+	delete item_pair;
+
+	rearrangeItems();
+
+	return true;
+}
+
+
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
new file mode 100644
index 00000000000..bd0b419f4ff
--- /dev/null
+++ b/indra/llui/llflatlistview.h
@@ -0,0 +1,262 @@
+/** 
+ * @file llflatlistview.h
+ * @brief LLFlatListView base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, 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_LLFLATLISTVIEW_H
+#define LL_LLFLATLISTVIEW_H
+
+#include "llscrollcontainer.h"
+
+
+class LLPanel;
+
+/**
+ * LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
+ * LLSD can be associated with each added item, it can keep data from an item in digested form.
+ * Associated LLSD's can be of any type (singular, a map etc.).
+ * Items (LLPanel's subclasses) can be of different height.
+ * The list is LLPanel created in itself and grows in height while new items are added. 
+ * 
+ * The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
+ * multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag 
+ * is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
+ * since any item of the list was selected.
+ *
+ * Examples of using this control are presented in Picks panel (Me Profile and Profile View), where this control is used to 
+ * manage the list of pick items.
+ *
+ * ASSUMPTIONS AND STUFF
+ * - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
+ * - Order of returned selected items are not guaranteed
+ * - The control assumes that all items being added are unique.
+ */
+class LLFlatListView : public LLScrollContainer
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
+	{
+		/** turning on/off selection support */
+		Optional<bool> allow_select;
+
+		/** turning on/off multiple selection (works while clicking and holding CTRL)*/
+		Optional<bool> multi_select;
+
+		/** don't allow to deselect all selected items (for mouse events on items only) */
+		Optional<bool> keep_one_selected;
+
+		/** padding between items */
+		Optional<U32> item_pad; 
+
+		Params();
+	};
+	
+	virtual ~LLFlatListView() { clear(); };
+
+
+	/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
+	virtual void reshape(S32 width, S32 height, BOOL called_from_parent  = TRUE);
+
+
+	/**
+	 * Adds and item and LLSD value associated with it to the list at specified position
+	 * @return true if the item was added, false otherwise 
+	 */
+	virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
+
+	/**
+	 * Insert item_to_add along with associated value to the list right after the after_item.
+	 * @return true if the item was successfully added, false otherwise
+	 */
+	virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null);
+
+	/** 
+	 * Remove specified item
+	 * @return true if the item was removed, false otherwise 
+	 */
+	virtual bool removeItem(LLPanel* item);
+
+	/** 
+	 * Remove an item specified by value
+	 * @return true if the item was removed, false otherwise 
+	 */
+	virtual bool removeItemByValue(const LLSD& value);
+
+	/** 
+	 * Remove an item specified by uuid
+	 * @return true if the item was removed, false otherwise 
+	 */
+	virtual bool removeItemByUUID(LLUUID& uuid);
+
+	/** 
+	 * Get an item by value 
+	 * @return the item as LLPanel if associated with value, NULL otherwise
+	 */
+	virtual LLPanel* getItemByValue(LLSD& value) const;
+
+	/** 
+	 * Select or deselect specified item based on select
+	 * @return true if succeed, false otherwise
+	 */
+	virtual bool selectItem(LLPanel* item, bool select = true);
+
+	/** 
+	 * Select or deselect an item by associated value based on select
+	 * @return true if succeed, false otherwise
+	 */
+	virtual bool selectItemByValue(const LLSD& value, bool select = true);
+
+	/** 
+	 * Select or deselect an item by associated uuid based on select
+	 * @return true if succeed, false otherwise
+	 */
+	virtual bool selectItemByUUID(LLUUID& uuid, bool select = true);
+
+
+	
+	/**
+	 * Get LLSD associated with the first selected item
+	 */
+	virtual LLSD getSelectedValue() const;
+
+	/**
+	 * Get LLSD's associated with selected items.
+	 * @param selected_values std::vector being populated with LLSD associated with selected items
+ 	 */
+	virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
+
+
+	/** 
+	 * Get LLUUID associated with selected item
+	 * @return LLUUID if such was associated with selected item 
+	 */
+	virtual LLUUID getSelectedUUID() const;
+
+	/** 
+	 * Get LLUUIDs associated with selected items
+	 * @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
+	 */
+	virtual void getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const;
+
+	/** Get the top selected item */
+	virtual LLPanel* getSelectedItem() const;
+
+	/** 
+	 * Get selected items
+	 * @param selected_items An std::vector being populated with pointers to selected items
+	 */
+	virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
+
+
+	/** Resets selection of items */
+	virtual void resetSelection();
+
+
+	/** Turn on/off multiple selection support */
+	void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
+
+	/** Turn on/off selection support */
+	void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
+
+
+	/** Get number of selected items in the list */
+	U32 numSelected() const {return mSelectedItemPairs.size(); }
+
+	/** Get number of items in the list */
+	U32 size() const { return mItemPairs.size(); }
+
+
+	/** Removes all items from the list */
+	virtual void clear();
+
+
+protected:
+
+	/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
+	typedef std::pair<LLPanel*, LLSD> item_pair_t;
+
+	typedef std::list<item_pair_t*> pairs_list_t;
+	typedef pairs_list_t::iterator pairs_iterator_t;
+	typedef pairs_list_t::const_iterator pairs_const_iterator_t;
+
+
+	friend class LLUICtrlFactory;
+	LLFlatListView(const LLFlatListView::Params& p);
+
+	/** Manage selection on mouse events */
+	void onItemMouseClick(item_pair_t* item_pair, MASK mask);
+
+	/** Updates position of items */
+	virtual void rearrangeItems();
+
+	virtual item_pair_t* getItemPair(LLPanel* item) const;
+
+	virtual item_pair_t* getItemPair(const LLSD& value) const;
+
+	virtual bool selectItemPair(item_pair_t* item_pair, bool select);
+
+	virtual bool isSelected(item_pair_t* item_pair) const;
+
+	virtual bool removeItemPair(item_pair_t* item_pair);
+
+
+private:
+
+	void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
+
+
+private:
+
+	LLPanel* mItemsPanel;
+
+	S32 mItemsNoScrollWidth;
+
+	S32 mBorderThickness;
+
+	/** Items padding */
+	U32 mItemPad;
+
+	/** Selection support flag */
+	bool mAllowSelection;
+
+	/** Multiselection support flag, ignored if selection is not supported */
+	bool mMultipleSelection;
+
+	bool mKeepOneItemSelected;
+
+	/** All pairs of the list */
+	pairs_list_t mItemPairs;
+
+	/** Selected pairs for faster access */
+	pairs_list_t mSelectedItemPairs;
+};
+
+#endif
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index fbcbb55b859..b87f645f3fc 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -38,30 +38,68 @@
 
 LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
 :	LLUICtrl(p)
+	, mSearchButton(NULL)
+	, mClearButton(NULL)
 {
-	S32 btn_top = p.search_button.top_pad + p.search_button.rect.height;
-	S32 btn_right = p.search_button.rect.width + p.search_button.left_pad;
-	LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad);
+	S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;
+	S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad;
+	LLRect srch_btn_rect(p.search_button.left_pad, srch_btn_top, srch_btn_right, p.search_button.top_pad);
+	S32 text_pad_left = p.text_pad_left;
 
+	if (p.search_button_visible)
+		text_pad_left += srch_btn_rect.getWidth();
+
+	// Set up line editor.
 	LLLineEditor::Params line_editor_params(p);
 	line_editor_params.name("filter edit box");
 	line_editor_params.rect(getLocalRect());
 	line_editor_params.follows.flags(FOLLOWS_ALL);
-	line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth());
+	line_editor_params.text_pad_left(text_pad_left);
+	line_editor_params.revert_on_esc(false);
 	line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+	line_editor_params.keystroke_callback(boost::bind(&LLSearchEditor::handleKeystroke, this));
 
 	mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
 	addChild(mSearchEditor);
 
-	LLButton::Params button_params(p.search_button);
-	button_params.name(std::string("clear filter"));
-	button_params.rect(search_btn_rect) ;
-	button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
-	button_params.tab_stop(false);
-	button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+	if (p.search_button_visible)
+	{
+		// Set up search button.
+		LLButton::Params srch_btn_params(p.search_button);
+		srch_btn_params.name(std::string("search button"));
+		srch_btn_params.rect(srch_btn_rect) ;
+		srch_btn_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP);
+		srch_btn_params.tab_stop(false);
+		srch_btn_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+	
+		mSearchButton = LLUICtrlFactory::create<LLButton>(srch_btn_params);
+		mSearchEditor->addChild(mSearchButton);
+	}
+
+	if (p.clear_button_visible)
+	{
+		// Set up clear button.
+		S32 clr_btn_width = getRect().getHeight(); // button is square, and as tall as search editor
+		LLRect clear_btn_rect(getRect().getWidth() - clr_btn_width, getRect().getHeight(), getRect().getWidth(), 0);
+		LLButton::Params clr_btn_params(p.clear_button);
+		clr_btn_params.name(std::string("clear button"));
+		clr_btn_params.rect(clear_btn_rect) ;
+		clr_btn_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
+		clr_btn_params.tab_stop(false);
+		clr_btn_params.click_callback.function(boost::bind(&LLSearchEditor::onClearButtonClick, this, _2));
+
+		mClearButton = LLUICtrlFactory::create<LLButton>(clr_btn_params);
+		mSearchEditor->addChild(mClearButton);
+	}
+}
+
+//virtual
+void LLSearchEditor::draw()
+{
+	if (mClearButton)
+		mClearButton->setVisible(!mSearchEditor->getWText().empty());
 
-	mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
-	mSearchEditor->addChild(mSearchButton);
+	LLUICtrl::draw();
 }
 
 //virtual
@@ -88,6 +126,12 @@ BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit
 	return mSearchEditor->setLabelArg(key, text);
 }
 
+//virtual
+void LLSearchEditor::setLabel( const LLStringExplicit &new_label )
+{
+	mSearchEditor->setLabel(new_label);
+}
+
 //virtual
 void LLSearchEditor::clear()
 {
@@ -96,3 +140,17 @@ void LLSearchEditor::clear()
 		mSearchEditor->clear();
 	}
 }
+
+void LLSearchEditor::onClearButtonClick(const LLSD& data)
+{
+	setText(LLStringUtil::null);
+	mSearchEditor->doDelete(); // force keystroke callback
+}
+
+void LLSearchEditor::handleKeystroke()
+{
+	if (mKeystrokeCallback)
+	{
+		mKeystrokeCallback(this, getValue());
+	}
+}
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index cd2867b4930..f395e7e8161 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -50,10 +50,15 @@ class LLSearchEditor : public LLUICtrl
 public:
 	struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
 	{
-		Optional<LLButton::Params> search_button;
+		Optional<LLButton::Params> search_button, clear_button;
+		Optional<bool> search_button_visible, clear_button_visible;
+		Optional<commit_callback_t> keystroke_callback;
 
 		Params()
 		: search_button("search_button")
+		, search_button_visible("search_button_visible")
+		, clear_button("clear_button")
+		, clear_button_visible("clear_button_visible")
 		{
 			name = "search_editor";
 		}
@@ -66,26 +71,29 @@ class LLSearchEditor : public LLUICtrl
 public:
 	virtual ~LLSearchEditor() {}
 
+	/*virtual*/ void	draw();
+
 	void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); }
 	const std::string& getText() const		{ return mSearchEditor->getText(); }
 
-
 	// LLUICtrl interface
 	virtual void	setValue(const LLSD& value );
 	virtual LLSD	getValue() const;
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
+	virtual void	setLabel( const LLStringExplicit &new_label );
 	virtual void	clear();
 
-	void	setKeystrokeCallback(LLLineEditor::callback_t callback, void* user_data)
-	{
-		if(mSearchEditor)
-			mSearchEditor->setKeystrokeCallback(callback,user_data);
-	}
+	void			setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
+
+protected:
+	void onClearButtonClick(const LLSD& data);
+	virtual void handleKeystroke();
 
-private:
+	commit_callback_t mKeystrokeCallback;
 	LLLineEditor* mSearchEditor;
 	LLButton* mSearchButton;
+	LLButton* mClearButton;
 };
 
 #endif  // LL_SEARCHEDITOR_H
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index cabd0be5223..3a13c91fac8 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -429,7 +429,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
 	BOOL handled = FALSE;
-	BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+	BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
 
 	if (has_scroll_arrows)
 	{
@@ -498,7 +498,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
 BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask )
 {
 	BOOL handled = FALSE;
-	BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+	BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
 
 	if (has_scroll_arrows)
 	{
@@ -540,7 +540,7 @@ BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask )
 BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
 {
 	BOOL handled = FALSE;
-	BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
+	BOOL has_scroll_arrows = (getMaxScrollPos() > 0)  && !getTabsHidden();
 
 	if (has_scroll_arrows)
 	{
@@ -1840,12 +1840,11 @@ void LLTabContainer::updateMaxScrollPos()
 
 void LLTabContainer::commitHoveredButton(S32 x, S32 y)
 {
-	if (hasMouseCapture())
+	if (!getTabsHidden() && hasMouseCapture())
 	{
 		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 		{
 			LLTabTuple* tuple = *iter;
-			tuple->mButton->setVisible( TRUE );
 			S32 local_x = x - tuple->mButton->getRect().mLeft;
 			S32 local_y = y - tuple->mButton->getRect().mBottom;
 			if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible())
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index d80c2af5684..1f7e5afaaec 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -633,7 +633,7 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) co
 		// did we find *something* with that name?
 		if (child)
 		{
-			llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T*).name() << llendl;
+			llwarns << "Found child named " << name << " but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << llendl;
 		}
 		result = getDefaultWidget<T>(name);
 		if (!result)
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index a121d327f78..2e64c10bb25 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,9 @@
 #include "llvoiceclient.h"
 
 static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+static LLDefaultChildRegistry::Register<LLAvatarListTmp> r_tmp("avatar_list_tmp");
+
+static const std::string COMMENT_TEXTBOX = "comment_text";
 
 LLAvatarList::Params::Params()
 :
@@ -302,3 +305,213 @@ void LLAvatarList::updateVolume()
 			icon_cell->setValue(getVolumeIcon(speaker_id));
 	}
 }
+
+
+
+
+#include "llavatarlistitem.h"
+
+LLAvatarListTmp::Params::Params()
+:
+volume_column_width("volume_column_width", 0)
+, online_go_first("online_go_first", true)
+{
+}
+
+
+
+LLAvatarListTmp::LLAvatarListTmp(const Params& p)
+:	LLFlatListView(p)
+, mHaveVolumeColumn(p.volume_column_width > 0)
+, mOnlineGoFirst(p.online_go_first)
+{
+	LLRect item_list_rect = getLocalRect();
+	item_list_rect.stretch( -getBorderWidth());
+
+	LLTextBox::Params text_p;
+	text_p.name(COMMENT_TEXTBOX);
+	text_p.border_visible(false);
+	text_p.rect(item_list_rect);
+	text_p.follows.flags(FOLLOWS_ALL);
+	addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
+}
+
+// virtual
+void LLAvatarListTmp::draw()
+{
+	LLFlatListView::draw();
+	if (mHaveVolumeColumn)
+	{
+		updateVolume();
+	}
+}
+
+std::vector<LLUUID> LLAvatarListTmp::getSelectedIDs()
+{
+	LLUUID selected_id;
+	std::vector<LLUUID> avatar_ids;
+
+	getSelectedUUIDs(avatar_ids);
+
+	return avatar_ids;
+}
+
+void LLAvatarListTmp::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+{
+	LLAvatarListItem* item = new LLAvatarListItem();
+	item->showStatus(true);
+	item->showInfoBtn(true);
+	item->showSpeakingIndicator(true);
+	item->setName(name);
+	item->setAvatarId(id);
+
+	item->childSetVisible("info_btn", false);
+
+	addItem(item, id, pos);
+
+	setCommentVisible(false);
+}
+
+BOOL LLAvatarListTmp::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+{
+	BOOL have_names = TRUE;
+
+	// Save selection.	
+	std::vector<LLUUID> selected_ids = getSelectedIDs();
+	LLUUID current_id = getSelectedUUID();
+	LLRect pos = getScrolledViewRect();
+
+	std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
+	clear();
+	for(; buddy_it != all_buddies.end(); ++buddy_it)
+	{
+		std::string name;
+		const LLUUID& buddy_id = *buddy_it;
+		have_names &= gCacheName->getFullName(buddy_id, name);
+		if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
+			continue;
+		addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+	}
+
+	// Changed item in place, need to request sort and update columns
+	// because we might have changed data in a column on which the user
+	// has already sorted. JC
+	//	updateSort(); // TODO: implement sorting
+
+	// re-select items
+	//	selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
+	selectItemByUUID(current_id);
+
+	scrollToShowRect(pos);
+
+
+	setCommentVisible(false);
+
+	return have_names;
+}
+
+
+const LLUUID LLAvatarListTmp::getCurrentID() const
+{
+	return getSelectedUUID();
+}
+
+void LLAvatarListTmp::setCommentText(const std::string& comment_text)
+{
+	getChild<LLTextBox>(COMMENT_TEXTBOX)->setValue(comment_text);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+// virtual overridden
+bool LLAvatarListTmp::removeItemPair(item_pair_t* item_pair)
+{
+	bool removed = LLFlatListView::removeItemPair(item_pair);
+	setCommentVisible(size() == 0);
+	return removed;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE SECTION
+//////////////////////////////////////////////////////////////////////////
+
+// static
+std::string LLAvatarListTmp::getVolumeIcon(const LLUUID& id)
+{
+	//
+	// Determine icon appropriate for the current avatar volume.
+	//
+	// *TODO: remove this in favor of LLOutputMonitorCtrl
+	// when ListView widget is implemented
+	// which is capable of containing arbitrary widgets.
+	//
+	static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
+	bool		muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
+	F32			power = gVoiceClient->getCurrentPower(id);
+	std::string	icon;
+
+	if (muted)
+	{
+		icon = default_monitor_params.image_mute.name;
+	}
+	else if (power == 0.f)
+	{
+		icon = default_monitor_params.image_off.name;
+	}
+	else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
+	{
+		S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
+		switch(icon_image_idx)
+		{
+		default:
+		case 0:
+			icon = default_monitor_params.image_on.name;
+			break;
+		case 1:
+			icon = default_monitor_params.image_level_1.name;
+			break;
+		case 2:
+			icon = default_monitor_params.image_level_2.name;
+			break;
+		}
+	}
+	else
+	{
+		// overdriven
+		icon = default_monitor_params.image_level_3.name;
+	}
+
+	return icon;
+}
+
+// Update volume column for all list rows.
+void LLAvatarListTmp::updateVolume()
+{
+	// TODO: implement via Listener
+	/*
+	item_list& items = getItemList();
+
+	for (item_list::iterator item_it = items.begin();
+	item_it != items.end();
+	++item_it)
+	{
+	LLScrollListItem* itemp = (*item_it);
+	LLUUID speaker_id = itemp->getUUID();
+
+	LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
+	if (icon_cell)
+	icon_cell->setValue(getVolumeIcon(speaker_id));
+	}
+	*/
+}
+
+void LLAvatarListTmp::setCommentVisible(bool visible) const
+{
+	getChildView(COMMENT_TEXTBOX)->setVisible(visible);
+}
+
+// EOF
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8b419dbb577..639ed83ada7 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -75,4 +75,46 @@ class LLAvatarList : public LLScrollListCtrl
 	bool mOnlineGoFirst;
 };
 
+
+#include "llflatlistview.h"
+
+class LLAvatarListTmp : public LLFlatListView
+{
+	LOG_CLASS(LLAvatarListTmp);
+public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> 
+	{
+		Optional<S32> volume_column_width;
+		Optional<bool> online_go_first;
+		Params();
+	};
+
+	LLAvatarListTmp(const Params&);
+	virtual	~LLAvatarListTmp() {}
+
+	/*virtual*/ void	draw();
+
+	BOOL update(const std::vector<LLUUID>& all_buddies,
+		const std::string& name_filter = LLStringUtil::null);
+
+	const LLUUID getCurrentID() const;
+	void setCommentText( const std::string& comment_text);
+
+protected:
+	std::vector<LLUUID> getSelectedIDs();
+	void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+	/*virtual*/ bool removeItemPair(item_pair_t* item_pair);
+
+private:
+	static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
+	void updateVolume(); // update volume for all avatars
+	void setCommentVisible(bool visible) const;
+
+	bool mHaveVolumeColumn;
+	bool mOnlineGoFirst;
+
+};
+
+
+
 #endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 253c2ee9a63..feae8202bcd 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -2,9 +2,9 @@
  * @file llavatarlistitem.cpp
  * @avatar list item source file
  *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
  * 
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
  * 
  * Second Life Viewer Source Code
  * The source code in this file ("Source Code") is provided by Linden Lab
@@ -33,70 +33,39 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llfloaterreg.h"
 #include "llavatarlistitem.h"
-#include "llagent.h"
-
 
-
-//---------------------------------------------------------------------------------
-LLAvatarListItem::LLAvatarListItem(const Params& p) : LLPanel()
+#include "llfloaterreg.h"
+#include "llagent.h"
+#include "lloutputmonitorctrl.h"
+#include "llavatariconctrl.h"
+#include "llbutton.h"
+
+
+LLAvatarListItem::LLAvatarListItem()
+:	LLPanel(),
+	mAvatarIcon(NULL),
+	mAvatarName(NULL),
+	mStatus(NULL),
+	mSpeakingIndicator(NULL),
+	mInfoBtn(NULL)
 {
-	mNeedsArrange = false;
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
-
-	mStatus = NULL;
-	mInfo = NULL;
-	mProfile = NULL;
-	mInspector = NULL;
-
-	mAvatar = getChild<LLAvatarIconCtrl>("avatar_icon");
-	//mAvatar->setValue(p.avatar_icon);
-	mName = getChild<LLTextBox>("name"); 
-	//mName->setText(p.user_name);
-	
-	init(p);
-
-	
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::init(const Params& p)
+BOOL  LLAvatarListItem::postBuild()
 {
-	mLocator = getChild<LLIconCtrl>("locator");
-
-	mStatus = getChild<LLTextBox>("user_status");
-
-	mInfo = getChild<LLButton>("info_btn");
-	mInfo->setVisible(false);
-	
-	mProfile = getChild<LLButton>("profile_btn");
-	mProfile->setVisible(false);
-
-	if(!p.buttons.locator)
-	{
-		mLocator->setVisible(false);
-		delete mLocator;
-		mLocator = NULL;
-	}
+	mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
+	mAvatarName = getChild<LLTextBox>("avatar_name");
+	mStatus = getChild<LLTextBox>("avatar_status");
 
-	if(!p.buttons.status)
-	{
-		mStatus->setVisible(false);
-		delete mStatus;
-		mStatus = NULL;
-	}
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+	mInfoBtn = getChild<LLButton>("info_btn");
 
-	if(!p.buttons.info)
-	{
-		delete mInfo;
-		mInfo = NULL;        
-	}
-	else
-	{
-		mInfo->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this));
-	}
+	mInfoBtn->setVisible(false);
+	mInfoBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this));
 
+/*
 	if(!p.buttons.profile)
 	{
 		delete mProfile;
@@ -125,150 +94,72 @@ void LLAvatarListItem::init(const Params& p)
 			mInfo->setRect(rect);
 		}
 	}
-	
+*/
+	return TRUE;
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
-	if(!mNeedsArrange)
-	{
-		LLView::reshape(width, height, called_from_parent);
-		return;
-	}
-
-	LLRect  rect;
-	S32     profile_delta = 0;
-	S32     width_delta = getRect().getWidth() - width; 
-
-	if(!mProfile)
-	{
-		profile_delta = 30;
-	}
-	else
-	{
-		rect.setLeftTopAndSize(mProfile->getRect().mLeft - width_delta, mProfile->getRect().mTop, mProfile->getRect().getWidth(), mProfile->getRect().getHeight());
-		mProfile->setRect(rect);
-	}
-
-	width_delta += profile_delta;
-
-	if(mInfo)
-	{
-		rect.setLeftTopAndSize(mInfo->getRect().mLeft - width_delta, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight());
-		mInfo->setRect(rect);
-	}
-
-	if(mLocator)
-	{
-		rect.setLeftTopAndSize(mLocator->getRect().mLeft - width_delta, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight());
-		mLocator->setRect(rect);
-	}
-
-	if(mStatus)
-	{
-		rect.setLeftTopAndSize(mStatus->getRect().mLeft - width_delta, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight());
-		mStatus->setRect(rect);
-	}
-
-	mNeedsArrange = false;
-	LLView::reshape(width, height, called_from_parent);
-}
-
-//---------------------------------------------------------------------------------
-LLAvatarListItem::~LLAvatarListItem()
-{
-}
-//---------------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------------
-BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
-{
-	mYPos = y;
-	mXPos = x;
-
-	return true;
-}
-
-//---------------------------------------------------------------------------------
 void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
 {
-	setTransparentColor( *(new LLColor4((F32)0.4, (F32)0.4, (F32)0.4)) );
+	childSetVisible("hovered_icon", true);
+	mInfoBtn->setVisible(true);
 
-	if(mInfo)
-		mInfo->setVisible(true);
-
-	if(mProfile)
-		mProfile->setVisible(true);
+	LLPanel::onMouseEnter(x, y, mask);
 }
 
-//---------------------------------------------------------------------------------
 void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
 {
-	if(mInfo)
-	{
-		if( mInfo->getRect().pointInRect(x, y) )
-			return;
-
-		mInfo->setVisible(false);
-	}
-
-	if(mProfile)
-	{
-		if( mProfile->getRect().pointInRect(x, y) )
-			return;
-		
-		mProfile->setVisible(false);
-	}
+	childSetVisible("hovered_icon", false);
+	mInfoBtn->setVisible(false);
 
-	setTransparentColor( *(new LLColor4((F32)0.3, (F32)0.3, (F32)0.3)) );
+	LLPanel::onMouseLeave(x, y, mask);
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setStatus(int status)
+void LLAvatarListItem::setStatus(const std::string& status)
 {
+	mStatus->setValue(status);
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setName(std::string name)
+void LLAvatarListItem::setName(const std::string& name)
 {
+	mAvatarName->setValue(name);
+	mAvatarName->setToolTip(name);
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::setAvatar(LLSD& data)
+void LLAvatarListItem::setAvatarId(const LLUUID& id)
 {
+	mAvatarIcon->setValue(id);
+	mSpeakingIndicator->setSpeakerId(id);
 }
 
-//---------------------------------------------------------------------------------
 void LLAvatarListItem::onInfoBtnClick()
 {
-	mInspector = LLFloaterReg::showInstance("inspect_avatar", gAgent.getID());
-
-	if (!mInspector)
-		return;
+	LLFloaterReg::showInstance("inspect_avatar", mAvatarIcon->getValue());
 
-	LLRect rect;
+	/* TODO fix positioning of inspector
 	localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);
 	
+	
+	LLRect rect;
 
 	// *TODO Vadim: rewrite this. "+= -" looks weird.
-	S32 delta = mYPos - mInspector->getRect().getHeight();
+	S32 delta = mYPos - inspector->getRect().getHeight();
 	if(delta < 0)
 	{
 		mYPos += -delta;
 	}
-
+	
 	rect.setLeftTopAndSize(mXPos, mYPos,
-		mInspector->getRect().getWidth(), mInspector->getRect().getHeight()); 
-	mInspector->setRect(rect);
-	mInspector->setFrontmost(true);
-	mInspector->setVisible(true);
-
+	inspector->getRect().getWidth(), inspector->getRect().getHeight()); 
+	inspector->setRect(rect);
+	inspector->setFrontmost(true);
+	inspector->setVisible(true);
+	*/
 }
 
-//---------------------------------------------------------------------------------
-void LLAvatarListItem::onProfileBtnClick()
+void LLAvatarListItem::setValue( const LLSD& value )
 {
+	if (!value.isMap()) return;;
+	if (!value.has("selected")) return;
+	childSetVisible("selected_icon", value["selected"]);
 }
 
-//---------------------------------------------------------------------------------
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index b41e0ff2090..dc5606e4c27 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -2,9 +2,9 @@
  * @file llavatarlistitem.h
  * @avatar list item header file
  *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
  * 
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
  * 
  * Second Life Viewer Source Code
  * The source code in this file ("Source Code") is provided by Linden Lab
@@ -30,75 +30,45 @@
  * $/LicenseInfo$
  */
 
-#include "llavatariconctrl.h"
-#include <llview.h>
-#include <llpanel.h>
-#include <llfloater.h>
-#include <lltextbox.h>
-#include <llbutton.h>
-#include <lluuid.h>
+#ifndef LL_LLAVATARLISTITEM_H
+#define LL_LLAVATARLISTITEM_H
 
-//#include "llfloaterminiinspector.h"
+#include "llpanel.h"
+#include "lloutputmonitorctrl.h"
+#include "llbutton.h"
+#include "lltextbox.h"
 
-class LLAvatarListItem : public LLPanel 
+class LLAvatarIconCtrl;
+
+class LLAvatarListItem : public LLPanel
 {
 public:
-	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
-	{
-		Optional<LLUUID>        	avatar_icon;
-		Optional<std::string>		user_name;
-		struct avatar_list_item_buttons
-		{
-			bool    status;
-			bool    info;
-			bool    profile;
-			bool    locator;
-			avatar_list_item_buttons() : status(true), info(true), profile(true), locator(true)
-			{};
-		} buttons;
-
-        Params() 
-		:	avatar_icon("avatar_icon"), 
-			user_name("user_name")
-        {};
-	};
-
-
-	LLAvatarListItem(const Params& p);
-	virtual	~LLAvatarListItem();
-
-    void reshape(S32 width, S32 height, BOOL called_from_parent);
-
-	//interface
-	void setStatus(int status);
-	void setName(std::string name);
-	void setAvatar(LLSD& data);
-    void needsArrange( void ) {mNeedsArrange = true;} 
-
+	LLAvatarListItem();
+	virtual ~LLAvatarListItem() {};
 
-	//event handlers
-	//mouse
-	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+	virtual BOOL postBuild();
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 	virtual void onMouseEnter(S32 x, S32 y, MASK mask);
-	//buttons
-	void onInfoBtnClick();
-	void onProfileBtnClick();
+	virtual void setValue(const LLSD& value);
 
-private:
-    LLAvatarIconCtrl* mAvatar;
-    LLIconCtrl* mLocator;
-	LLTextBox*	mName;
-	LLTextBox*	mStatus;
-	LLButton*	mInfo;
-	LLButton*	mProfile;
+	void setStatus(const std::string& status);
+	void setName(const std::string& name);
+	void setAvatarId(const LLUUID& id);
+
+	void onInfoBtnClick();
 
-	S32 mYPos;
-	S32 mXPos;
+	void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); }
+	void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); }
+	void showStatus(bool show_status) {mStatus->setVisible(show_status); }
 
-	LLFloater*	mInspector;
-    bool        mNeedsArrange;
 
-    //
-    void init(const Params& p);
+private:
+	LLAvatarIconCtrl*mAvatarIcon;
+	LLTextBox* mAvatarName;
+	LLTextBox* mStatus;
+	
+	LLOutputMonitorCtrl* mSpeakingIndicator;
+	LLButton* mInfoBtn;
 };
+
+#endif //LL_LLAVATARLISTITEM_H
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index e5acf621893..42ed783f940 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1140,6 +1140,8 @@ LLTalkButton::LLTalkButton(const Params& p)
 	LLOutputMonitorCtrl::Params monitor_params = p.monitor;
 	monitor_params.draw_border(false);
 	monitor_params.rect(monitor_rect);
+	monitor_params.auto_update(true);
+	monitor_params.speaker_id(gAgentID);
 	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
 	mSpeakBtn->addChild(mOutputMonitor);
 
@@ -1151,17 +1153,6 @@ LLTalkButton::~LLTalkButton()
 {
 }
 
-void LLTalkButton::draw()
-{
-	// Always provide speaking feedback.  User can trigger speaking
-	// with keyboard or middle-mouse shortcut.
-	mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID()));
-	mOutputMonitor->setIsTalking( gVoiceClient->getUserPTTState() );
-	mSpeakBtn->setToggleState( gVoiceClient->getUserPTTState() );
-
-	LLUICtrl::draw();
-}
-
 void LLTalkButton::setSpeakBtnToggleState(bool state)
 {
 	mSpeakBtn->setToggleState(state);
@@ -1198,13 +1189,14 @@ void LLTalkButton::onClick_ShowBtn()
 	rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
 	mPrivateCallPanel->setRect(rect);
 
-	LLAvatarListItem::Params p;
-	p.buttons.status = true;
-	p.buttons.info = true;
-	p.buttons.profile = false;
-	p.buttons.locator = true;
 
-	mPrivateCallPanel->addItem(new LLAvatarListItem(p));
+	LLAvatarListItem* item = new LLAvatarListItem();
+	item->showStatus(true);
+	item->showInfoBtn(true);
+	item->showSpeakingIndicator(true);
+	item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE);
+
+	mPrivateCallPanel->addItem(item);
 	mPrivateCallPanel->setVisible(TRUE);
 	mPrivateCallPanel->setFrontmost(TRUE);
 
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 91f55915ed0..52bd7dbc315 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -780,7 +780,6 @@ class LLTalkButton : public LLUICtrl
 
 	/*virtual*/ ~LLTalkButton();
 
-	/*virtual*/ void draw();
 	void setSpeakBtnToggleState(bool state);
 
 protected:
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 94ea20893a5..f4c4f38008b 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -77,21 +77,11 @@ bool LLFloaterCamera::inAvatarViewMode()
 	return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW;
 }
 
-void LLFloaterCamera::resetFreeCameraMode()
+void LLFloaterCamera::resetCameraMode()
 {
-	if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA)
-	{
-		/* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look 
-		In such case we are unable to determine that we will be into Mouse Look view */
-		if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW)
-		{
-			setMode(CAMERA_CTRL_MODE_ORBIT);
-		}
-		else
-		{
-			setMode(mPrevMode);
-		}
-	}
+	LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
+	if (!floater_camera) return;
+	floater_camera->switchMode(CAMERA_CTRL_MODE_ORBIT);
 }
 
 void LLFloaterCamera::update()
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 04554c6493c..1181c443bfa 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -62,9 +62,8 @@ class LLFloaterCamera
 
 	static void toPrevModeIfInAvatarViewMode();
 
-	/* resets free camera mode to the previous mode */
-	//*TODO remove, if it won't be used by LLToolCamera::handleDeselect()
-	void resetFreeCameraMode();
+	/** resets current camera mode to orbit mode */
+	static void resetCameraMode();
 
 	/* determines actual mode and updates ui */
 	void update();
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 0262e40803e..a47477c446f 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -35,6 +35,7 @@
 
 #include "llnotificationhandler.h"
 
+#include "llagentdata.h"
 #include "llbottomtray.h"
 #include "llviewercontrol.h"
 #include "lltoastimpanel.h"
@@ -77,9 +78,15 @@ void LLIMHandler::processNotification(const LLSD& notify)
 	{
 		LLSD substitutions = notification->getSubstitutions();
 
+		// According to comments in LLIMMgr::addMessage(), if we get message
+		// from ourselves, the sender id is set to null. This fixes EXT-875.
+		LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+		if (avatar_id.isNull())
+			avatar_id = gAgentID;
+
 		LLToastIMPanel::Params im_p;
 		im_p.notification = notification;
-		im_p.avatar_id = substitutions["FROM_ID"].asUUID();
+		im_p.avatar_id = avatar_id;
 		im_p.from = substitutions["FROM"].asString();
 		im_p.time = substitutions["TIME"].asString();
 		im_p.message = substitutions["MESSAGE"].asString();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 901b3351c86..9ef98afe946 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -101,7 +101,8 @@ void toast_callback(const LLSD& msg){
 		args["FROM_ID"] = msg["from_id"];
 		args["SESSION_ID"] = msg["session_id"];
 
-		LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
+		//LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
+		LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::toggle, msg["session_id"].asUUID()));
 	}
 }
 
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index d4a9be0355f..764e093bcc3 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -32,6 +32,9 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
 #include "llnearbychatbar.h"
 #include "llbottomtray.h"
 #include "llagent.h"
@@ -45,7 +48,7 @@
 
 S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
 
-// legacy calllback glue
+// legacy callback glue
 void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
 
 static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
@@ -64,6 +67,7 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p)
 	: LLComboBox(p)
 	, mGestureLabelTimer()
 	, mLabel(p.label)
+	, mViewAllItemIndex(0)
 {
 	setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this));
 
@@ -102,6 +106,11 @@ void LLGestureComboBox::refreshGestures()
 	}
 
 	sortByName();
+
+	// store index followed by the last added Gesture and add View All item at bottom
+	mViewAllItemIndex = idx;
+	addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
+
 	// Insert label after sorting, at top, with separator below it
 	addSeparator(ADD_TOP);		
 	addSimpleElement(mLabel, ADD_TOP);
@@ -128,6 +137,15 @@ void LLGestureComboBox::onCommitGesture()
 		}
 
 		index = gestures->getSelectedValue().asInteger();
+
+		if (mViewAllItemIndex == index)
+		{
+			// The same behavior as Ctrl+G. EXT-823
+			LLFloaterReg::toggleInstance("gestures");
+			gestures->selectFirstItem();
+			return;
+		}
+
 		LLMultiGesture* gesture = mGestures.at(index);
 		if(gesture)
 		{
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 19177e37b3d..f310740f424 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -63,6 +63,7 @@ class LLGestureComboBox
 	LLFrameTimer mGestureLabelTimer;
 	std::vector<LLMultiGesture*> mGestures;
 	std::string mLabel;
+	LLSD::Integer mViewAllItemIndex;
 };
 
 class LLNearbyChatBar
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index d088c457100..49b48f5a8ea 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -38,6 +38,8 @@
 
 // viewer includes
 #include "llvoiceclient.h"
+#include "llmutelist.h"
+#include "llagent.h"
 
 // default options set in output_monitor.xml
 static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor");
@@ -58,7 +60,9 @@ LLOutputMonitorCtrl::Params::Params()
 	image_on("image_on"),
 	image_level_1("image_level_1"),
 	image_level_2("image_level_2"),
-	image_level_3("image_level_3")
+	image_level_3("image_level_3"),
+	auto_update("auto_update"),
+	speaker_id("speaker_id")
 {
 	draw_border = true;
 	name = "output_monitor";
@@ -69,14 +73,14 @@ LLOutputMonitorCtrl::Params::Params()
 LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 :	LLView(p),
 	mPower(0),
-	mIsMuted(true),
-	mIsTalking(false),
 	mImageMute(p.image_mute),
 	mImageOff(p.image_off),
 	mImageOn(p.image_on),
 	mImageLevel1(p.image_level_1),
 	mImageLevel2(p.image_level_2),
-	mImageLevel3(p.image_level_3)
+	mImageLevel3(p.image_level_3),
+	mAutoUpdate(p.auto_update),
+	mSpeakerId(p.speaker_id)
 {
 	//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
 	//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -99,10 +103,14 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	//sRectHeightRatio	= output_monitor_rect_height_ratio;
 
 	mBorder = p.draw_border;
+
+	//with checking mute state
+	setSpeakerId(mSpeakerId);
 }
 
 LLOutputMonitorCtrl::~LLOutputMonitorCtrl()
 {
+	LLMuteList::getInstance()->removeObserver(this);
 }
 
 void LLOutputMonitorCtrl::setPower(F32 val)
@@ -121,6 +129,12 @@ void LLOutputMonitorCtrl::draw()
 	const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
 	const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
 
+	if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
+	{
+		setPower(gVoiceClient->getCurrentPower(mSpeakerId));
+		setIsTalking(gVoiceClient->getUserPTTState());
+	}
+
 	LLPointer<LLUIImage> icon;
 	if (mIsMuted)
 	{
@@ -205,3 +219,29 @@ void LLOutputMonitorCtrl::draw()
 	if(mBorder)
 		gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
 }
+
+void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id)
+{
+	if (speaker_id.isNull()) return;
+
+	mSpeakerId = speaker_id;
+
+	//mute management
+	if (mAutoUpdate)
+	{
+		if (speaker_id == gAgentID)
+		{
+			setIsMuted(false);
+		}
+		else
+		{
+			setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId));
+			LLMuteList::getInstance()->addObserver(this);
+		}
+	}
+}
+
+void LLOutputMonitorCtrl::onChange()
+{
+	setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId));
+}
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 98b2fe9dc6d..7a7b8bc3a18 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -35,6 +35,7 @@
 
 #include "v4color.h"
 #include "llview.h"
+#include "llmutelist.h"
 
 class LLTextBox;
 class LLUICtrlFactory;
@@ -44,7 +45,7 @@ class LLUICtrlFactory;
 //
 
 class LLOutputMonitorCtrl
-: public LLView
+: public LLView, LLMuteListObserver
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
@@ -56,6 +57,8 @@ class LLOutputMonitorCtrl
 								image_level_1,
 								image_level_2,
 								image_level_3;
+		Optional<bool>		auto_update;
+		Optional<LLUUID>	speaker_id;
 
 		Params();
 	};
@@ -80,6 +83,11 @@ class LLOutputMonitorCtrl
 	// correct button image.
 	void			setIsTalking(bool val) { mIsTalking = val; }
 
+	void			setSpeakerId(const LLUUID& speaker_id);
+
+	//called by mute list
+	virtual void onChange();
+
 private:
 	//static LLColor4	sColorMuted;
 	//static LLColor4	sColorNormal;
@@ -89,6 +97,8 @@ class LLOutputMonitorCtrl
 	//static F32		sRectWidthRatio;
 	//static F32		sRectHeightRatio;
 	
+	
+
 	F32				mPower;
 	bool			mIsMuted;
 	bool			mIsTalking;
@@ -98,6 +108,12 @@ class LLOutputMonitorCtrl
 	LLPointer<LLUIImage> mImageLevel1;
 	LLPointer<LLUIImage> mImageLevel2;
 	LLPointer<LLUIImage> mImageLevel3;
+
+	/** whether to deal with gVoiceClient directly */
+	bool			mAutoUpdate;
+
+	/** uuid of a speaker being monitored */
+	LLUUID			mSpeakerId;
 };
 
 #endif
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index e0b7aeb77e3..b7f2f67a9ac 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -446,7 +446,7 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g
 
 void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data)
 {
-	childSetValue("register_date", avatar_data->born_on);
+	childSetValue("register_date", LLAvatarPropertiesProcessor::ageFromDate(avatar_data->born_on));
 	childSetValue("sl_description_edit", avatar_data->about_text);
 	childSetValue("fl_description_edit",avatar_data->fl_about_text);
 	childSetValue("2nd_life_pic", avatar_data->image_id);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 48c9c167807..378a09e3154 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -36,6 +36,7 @@
 
 #include "llagent.h"
 #include "llbutton.h"
+#include "llfiltereditor.h"
 #include "llfloatergroupinvite.h"
 #include "llavataractions.h"
 #include "lliconctrl.h"
@@ -49,7 +50,6 @@
 #include "lltabcontainer.h"
 #include "lltextbox.h"
 #include "lltexteditor.h"
-#include "llsearcheditor.h"
 #include "llviewertexturelist.h"
 #include "llviewerwindow.h"
 #include "llfocusmgr.h"
@@ -477,14 +477,12 @@ BOOL LLPanelGroupSubTab::postBuild()
 {
 	// Hook up the search widgets.
 	bool recurse = true;
-	mSearchEditor = getChild<LLSearchEditor>("filter_input", recurse);
+	mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse);
 
 	if (!mSearchEditor) 
 		return FALSE;
 
-	mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::onClickSearch, this));
-	mSearchEditor->setKeystrokeCallback(onSearchKeystroke, this);
-
+	mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
 	
 	// Get icons for later use.
 	mActionIcons.clear();
@@ -517,26 +515,6 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
 	}
 }
 
-// static
-void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data)
-{
-	LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
-	self->handleSearchKeystroke(caller);
-
-}
-
-void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller)
-{
-	setSearchFilter( caller->getText() );
-}
-
-// static 
-void LLPanelGroupSubTab::onClickSearch()
-{
-	setSearchFilter( mSearchEditor->getText() );
-}
- 
-
 void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
 {
 	lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl;
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 2a0f31fa0f9..bd5fc1d2350 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -35,6 +35,7 @@
 
 #include "llpanelgroup.h"
 
+class LLFilterEditor;
 class LLNameListCtrl;
 class LLPanelGroupSubTab;
 class LLPanelGroupMembersSubTab;
@@ -43,7 +44,6 @@ class LLPanelGroupActionsSubTab;
 class LLScrollListCtrl;
 class LLScrollListItem;
 class LLTextEditor;
-class LLSearchEditor;
 
 // Forward declare for friend usage.
 //virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*);
@@ -111,11 +111,6 @@ class LLPanelGroupSubTab : public LLPanelGroupTab
 	// This allows sub-tabs to collect child widgets from a higher level in the view hierarchy.
 	virtual BOOL postBuildSubTab(LLView* root) { return TRUE; }
 
-	static void onSearchKeystroke(LLLineEditor* caller, void* user_data);
-	void handleSearchKeystroke(LLLineEditor* caller);
-
-	void onClickSearch();
-
 	virtual void setSearchFilter( const std::string& filter );
 
 	virtual void activate();
@@ -148,7 +143,7 @@ class LLPanelGroupSubTab : public LLPanelGroupTab
 	LLPanel* mHeader;
 	LLPanel* mFooter;
 
-	LLSearchEditor*	mSearchEditor;
+	LLFilterEditor*	mSearchEditor;
 
 	std::string mSearchFilter;
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 42aa21c13ee..309a97a9f2b 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -401,6 +401,19 @@ LLPanelPeople::~LLPanelPeople()
 	LLView::deleteViewByHandle(mRecentViewSortMenuHandle);
 
 }
+void onAvatarListTmpDoubleClicked(LLAvatarListTmp* list)
+{
+	LLUUID clicked_id = list->getCurrentID();
+
+	if (clicked_id.isNull())
+		return;
+
+#if 0 // SJB: Useful for testing, but not currently functional or to spec
+	LLAvatarActions::showProfile(clicked_id);
+#else // spec says open IM window
+	LLAvatarActions::startIM(clicked_id);
+#endif
+}
 
 BOOL LLPanelPeople::postBuild()
 {
@@ -417,7 +430,7 @@ BOOL LLPanelPeople::postBuild()
 
 	mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
 
-	mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+	mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarListTmp>("avatar_list");
 	mGroupList = getChild<LLGroupList>("group_list");
 
 	LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
@@ -432,11 +445,11 @@ BOOL LLPanelPeople::postBuild()
 	mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList));
 	mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList));
 	mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList));
-	mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList));
+	mRecentList->setDoubleClickCallback(boost::bind(onAvatarListTmpDoubleClicked, mRecentList));
 	mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList));
 	mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList));
 	mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList));
-	mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList));
+	mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
 
 	mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
 	mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 3358a70bac1..c0c2f706142 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -40,6 +40,7 @@
 class LLFilterEditor;
 class LLTabContainer;
 class LLAvatarList;
+class LLAvatarListTmp;
 class LLGroupList;
 
 class LLPanelPeople : public LLPanel
@@ -118,7 +119,7 @@ class LLPanelPeople : public LLPanel
 	LLAvatarList*			mOnlineFriendList;
 	LLAvatarList*			mAllFriendList;
 	LLAvatarList*			mNearbyList;
-	LLAvatarList*			mRecentList;
+	LLAvatarListTmp*		mRecentList;
 	LLGroupList*			mGroupList;
 
 	LLHandle<LLView>		mGroupPlusMenuHandle;
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 457109f8693..7a19b8877e6 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -68,7 +68,6 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
 :	LLPanel(),
 	mParcelID(),
 	mRequestedID(),
-	mPosRegion(),
 	mLandmarkID(),
 	mMinHeight(0),
 	mScrollingPanel(NULL),
@@ -82,8 +81,6 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo()
 	{
 		LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
 	}
-
-	LLViewerParcelMgr::getInstance()->removeObserver(this);
 }
 
 BOOL LLPanelPlaceInfo::postBuild()
@@ -254,7 +251,6 @@ void LLPanelPlaceInfo::resetLocation()
 	mParcelID.setNull();
 	mRequestedID.setNull();
 	mLandmarkID.setNull();
-	mPosRegion.clearVec();
 	std::string not_available = getString("not_available");
 	mMaturityRatingText->setValue(not_available);
 	mParcelOwner->setValue(not_available);
@@ -330,8 +326,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 
 	getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
 
-	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
-
 	switch(type)
 	{
 		case CREATE_LANDMARK:
@@ -339,15 +333,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 		break;
 
 		case AGENT:
-			if (parcel_mgr)
-			{
-				// If information is requested for current agent location
-				// start using LLViewerParcelMgr for land selection.
-				parcel_mgr->addObserver(this);
-				parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
-			}
-
-		// Fall through to PLACE case
 		case PLACE:
 			mCurrentTitle = getString("title_place");
 
@@ -366,16 +351,7 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 		break;
 	}
 
-	if (type != AGENT && parcel_mgr != NULL)
-	{
-		if (!parcel_mgr->selectionEmpty())
-		{
-			parcel_mgr->deselectUnused();
-		}
-		parcel_mgr->removeObserver(this);
-	}
-
-	if (type != PLACE)
+	if (type != AGENT)
 		toggleMediaPanel(FALSE);
 
 	mInfoType = type;
@@ -442,12 +418,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
 	}
 
-	if( !parcel_data.name.empty())
+	if(!parcel_data.name.empty())
 	{
 		mParcelName->setText(parcel_data.name);
 	}
+	else
+	{
+		mParcelName->setText(LLStringUtil::null);
+	}
 
-	if( !parcel_data.desc.empty())
+	if(!parcel_data.desc.empty())
 	{
 		mDescEditor->setText(parcel_data.desc);
 	}
@@ -471,21 +451,12 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 	//because we deal with remote parcel response format
 	bool isForSale = (parcel_data.flags & DFQ_FOR_SALE)? TRUE : FALSE;
 	getChild<LLIconCtrl>("icon_for_sale")->setVisible(isForSale);
-	
-	// Just use given region position for display
-	S32 region_x = llround(mPosRegion.mV[0]);
-	S32 region_y = llround(mPosRegion.mV[1]);
-	S32 region_z = llround(mPosRegion.mV[2]);
 
-	// If the region position is zero, grab position from the global
-	if(mPosRegion.isExactlyZero())
-	{
-		region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
-		region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
-		region_z = llround(parcel_data.global_z);
-	}
+	S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+	S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+	S32 region_z = llround(parcel_data.global_z);
 
-	std::string name;
+	std::string name = getString("not_available");
 	if (!parcel_data.sim_name.empty())
 	{
 		name = llformat("%s (%d, %d, %d)",
@@ -495,17 +466,23 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 	
 	if (mInfoType == CREATE_LANDMARK)
 	{
-		mTitleEditor->setText(parcel_data.name);
+
+		if (parcel_data.name.empty())
+		{
+			mTitleEditor->setText(name);
+		}
+		else
+		{
+			mTitleEditor->setText(parcel_data.name);
+		}
+
 		mNotesEditor->setText(LLStringUtil::null);
 	}
 }
 
-void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
-									 const LLUUID& region_id,
-									 const LLVector3d& pos_global)
+void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
+										 const LLVector3d& pos_global)
 {
-	mPosRegion = pos_region;
-
 	LLViewerRegion* region = gAgent.getRegion();
 	if (!region)
 		return;
@@ -514,6 +491,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
 	std::string url = region->getCapability("RemoteParcelRequest");
 	if (!url.empty())
 	{
+		F32 region_x = (F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS);
+		F32 region_y = (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS);
+		LLVector3 pos_region(region_x, region_y, (F32)pos_global.mdV[VZ]);
+
 		body["location"] = ll_sd_from_vector3(pos_region);
 		if (!region_id.isNull())
 		{
@@ -532,12 +513,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
 	}
 }
 
-void LLPanelPlaceInfo::displayAgentParcelInfo()
+void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,
+											  LLViewerRegion* region,
+											  const LLVector3d& pos_global)
 {
-	mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
-
-	LLParcel* parcel = mParcel->getParcel();
-	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
 	if (!region || !parcel)
 		return;
 
@@ -568,14 +547,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
 	parcel_data.name = parcel->getName();
 	parcel_data.sim_name = gAgent.getRegion()->getName();
 	parcel_data.snapshot_id = parcel->getSnapshotID();
-	LLVector3d global_pos = gAgent.getPositionGlobal();
-	parcel_data.global_x = global_pos.mdV[0];
-	parcel_data.global_y = global_pos.mdV[1];
-	parcel_data.global_z = global_pos.mdV[2];
-
-	mPosRegion = gAgent.getPositionAgent();
-
-	processParcelInfo(parcel_data);
+	parcel_data.global_x = pos_global.mdV[0];
+	parcel_data.global_y = pos_global.mdV[1];
+	parcel_data.global_z = pos_global.mdV[2];
 
 	std::string on = getString("on");
 	std::string off = getString("off");
@@ -589,7 +563,7 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
 	{
 		mVoiceText->setText(off);
 	}
-	
+
 	if (!region->getBlockFly() && parcel->getAllowFly())
 	{
 		mFlyText->setText(on);
@@ -769,14 +743,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
 		}
 	}
 
-	getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
-}
+	processParcelInfo(parcel_data);
 
-// virtual
-void LLPanelPlaceInfo::changed()
-{
-	resetLocation();
-	displayAgentParcelInfo();
+	getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
 }
 
 void LLPanelPlaceInfo::updateEstateName(const std::string& name)
@@ -835,7 +804,10 @@ void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
 		}
 	}
 
-	if (item_value != current_value &&
+	LLStringUtil::trim(current_value);
+
+	if (!current_value.empty() &&
+		item_value != current_value &&
 	    gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
 	{
 		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
@@ -867,11 +839,17 @@ void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id)
 	if (name.empty())
 	{
 		name = mParcelName->getText();
+
+		// If no parcel exists use the region name instead.
+		if (name.empty())
+		{
+			name = mRegionName->getText();
+		}
 	}
 
 	LLStringUtil::replaceChar(desc, '\n', ' ');
 	// If no folder chosen use the "Landmarks" folder.
-	LLLandmarkActions::createLandmarkHere(name, desc, 
+	LLLandmarkActions::createLandmarkHere(name, desc,
 		folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK));
 }
 
@@ -884,10 +862,14 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
 	pick_data.pick_id = LLUUID::generateNewID();
 	pick_data.creator_id = gAgentID;
 
-	//legacy var  need to be deleted
+	//legacy var needs to be deleted
 	pick_data.top_pick = FALSE;
 	pick_data.parcel_id = mParcelID;
 	pick_data.name = mParcelName->getText();
+	if (pick_data.name.empty())
+	{
+		pick_data.name = mRegionName->getText();
+	}
 	pick_data.desc = mDescEditor->getText();
 	pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
 	pick_data.pos_global = global_pos;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 60f35cd0c12..32ae4334aae 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -42,17 +42,17 @@
 
 #include "llpanelmedia.h"
 #include "llremoteparcelrequest.h"
-#include "llviewerparcelmgr.h"
 
 class LLButton;
 class LLInventoryItem;
 class LLLineEditor;
-class LLParcelSelection;
+class LLParcel;
 class LLTextBox;
 class LLTextEditor;
 class LLTextureCtrl;
+class LLViewerRegion;
 
-class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver
+class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 {
 public:
 	enum INFO_TYPE
@@ -99,16 +99,14 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObs
 
 	// Displays information about a remote parcel.
 	// Sends a request to the server.
-	void displayParcelInfo(const LLVector3& pos_region,
-						   const LLUUID& region_id,
+	void displayParcelInfo(const LLUUID& region_id,
 						   const LLVector3d& pos_global);
 
-	// Displays information about the parcel the agent is currently on
+	// Displays information about the currently selected parcel
 	// without sending a request to the server.
-	void displayAgentParcelInfo();
-
-	// Called on parcel selection change by LLViewerParcelMgr.
-	/*virtual*/ void changed();
+	void displaySelectedParcelInfo(LLParcel* parcel,
+								LLViewerRegion* region,
+								const LLVector3d& pos_global);
 
 	void updateEstateName(const std::string& name);
 	void updateEstateOwnerName(const std::string& name);
@@ -135,7 +133,6 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObs
 	LLUUID			mParcelID;
 	LLUUID			mRequestedID;
 	LLUUID			mLandmarkID;
-	LLVector3		mPosRegion;
 	std::string		mCurrentTitle;
 	S32				mMinHeight;
 	INFO_TYPE 		mInfoType;
@@ -186,8 +183,6 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObs
 	LLPanel*            mScrollingPanel;
 	LLPanel*			mInfoPanel;
 	LLMediaPanel*		mMediaPanel;
-
-	LLSafeHandle<LLParcelSelection>	mParcel;
 };
 
 #endif // LL_LLPANELPLACEINFO_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index bc740bd865a..11ddc3dd9ae 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -31,10 +31,14 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llpanelplaces.h"
+
 #include "llassettype.h"
 #include "llwindow.h"
 
+#include "llinventory.h"
 #include "lllandmark.h"
+#include "llparcel.h"
 
 #include "llfloaterreg.h"
 #include "llnotifications.h"
@@ -44,10 +48,11 @@
 #include "lluictrlfactory.h"
 
 #include "llagent.h"
+#include "llfloaterworldmap.h"
+#include "llinventorymodel.h"
 #include "lllandmarkactions.h"
 #include "lllandmarklist.h"
-#include "llfloaterworldmap.h"
-#include "llpanelplaces.h"
+#include "llpanelplaceinfo.h"
 #include "llpanellandmarks.h"
 #include "llpanelteleporthistory.h"
 #include "llsidetray.h"
@@ -57,6 +62,7 @@
 #include "llviewermenu.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
+#include "llviewerwindow.h"
 
 static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
 static const std::string AGENT_INFO_TYPE			= "agent";
@@ -69,9 +75,41 @@ static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history";
 static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
 static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
 static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
-static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global);
 static void onSLURLBuilt(std::string& slurl);
 
+//Observer classes
+class LLPlacesParcelObserver : public LLParcelObserver
+{
+public:
+	LLPlacesParcelObserver(LLPanelPlaces* places_panel)
+	: mPlaces(places_panel) {}
+
+	/*virtual*/ void changed()
+	{
+		if (mPlaces)
+			mPlaces->changedParcelSelection();
+	}
+
+private:
+	LLPanelPlaces*		mPlaces;
+};
+
+class LLPlacesInventoryObserver : public LLInventoryObserver
+{
+public:
+	LLPlacesInventoryObserver(LLPanelPlaces* places_panel)
+	: mPlaces(places_panel) {}
+
+	/*virtual*/ void changed(U32 mask)
+	{
+		if (mPlaces)
+			mPlaces->changedInventory(mask);
+	}
+
+private:
+	LLPanelPlaces*		mPlaces;
+};
+
 static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
 
 LLPanelPlaces::LLPanelPlaces()
@@ -82,11 +120,14 @@ LLPanelPlaces::LLPanelPlaces()
 		mPlaceInfo(NULL),
 		mItem(NULL),
 		mPlaceMenu(NULL),
-		mLandmarkMenu(NULL),		
+		mLandmarkMenu(NULL),
 		mLandmarkFoldersMenuHandle(),
 		mPosGlobal()
 {
-	gInventory.addObserver(this);
+	mParcelObserver = new LLPlacesParcelObserver(this);
+	mInventoryObserver = new LLPlacesInventoryObserver(this);
+
+	gInventory.addObserver(mInventoryObserver);
 
 	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(
 			boost::bind(&LLPanelPlaces::onAgentParcelChange, this));
@@ -96,10 +137,15 @@ LLPanelPlaces::LLPanelPlaces()
 
 LLPanelPlaces::~LLPanelPlaces()
 {
-	if (gInventory.containsObserver(this))
-		gInventory.removeObserver(this);
-	
+	if (gInventory.containsObserver(mInventoryObserver))
+		gInventory.removeObserver(mInventoryObserver);
+
+	LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
+
 	LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle);
+
+	delete mInventoryObserver;
+	delete mParcelObserver;
 }
 
 BOOL LLPanelPlaces::postBuild()
@@ -173,15 +219,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	if (mPlaceInfoType == AGENT_INFO_TYPE)
 	{
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT);
-
-		mPosGlobal = gAgent.getPositionGlobal();
 	}
 	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
 	{
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
-		mPlaceInfo->displayAgentParcelInfo();
-		
-		mPosGlobal = gAgent.getPositionGlobal();
 	}
 	else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
 	{
@@ -189,7 +230,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 		LLInventoryItem* item = gInventory.getItem(item_uuid);
 		if (!item)
 			return;
-		
+
 		setItem(item);
 	}
 	else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
@@ -204,9 +245,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 								key["z"].asReal());
 
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
-		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
-									  LLUUID(),
-									  mPosGlobal);
+		mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);
 	}
 	else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
 	{
@@ -219,9 +258,30 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
 		mPlaceInfo->updateLastVisitedText(hist_items[index].mDate);
-		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
-									  LLUUID(),
-									  mPosGlobal);
+		mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);
+	}
+
+	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+	if (!parcel_mgr)
+		return;
+
+	// Start using LLViewerParcelMgr for land selection if
+	// information about nearby land is requested.
+	// Otherwise stop using land selection and deselect land.
+	if (mPlaceInfoType == AGENT_INFO_TYPE ||
+		mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+	{
+		parcel_mgr->addObserver(mParcelObserver);
+		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
+	}
+	else
+	{
+		parcel_mgr->removeObserver(mParcelObserver);
+
+		if (!parcel_mgr->selectionEmpty())
+		{
+			parcel_mgr->deselectLand();
+		}
 	}
 }
 
@@ -259,9 +319,7 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
 	LLUUID region_id;
 	landmark->getRegionID(region_id);
 	landmark->getGlobalPos(mPosGlobal);
-	mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
-								  region_id,
-								  mPosGlobal);
+	mPlaceInfo->displayParcelInfo(region_id, mPosGlobal);
 }
 
 void LLPanelPlaces::onFilterEdit(const std::string& search_string)
@@ -382,7 +440,7 @@ void LLPanelPlaces::onOverflowButtonClicked()
 		 mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL)
 	{
 		menu = mPlaceMenu;
-		
+
 		// Enable adding a landmark only for agent current parcel and if
 		// there is no landmark already pointing to that parcel in agent's inventory.
 		menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible &&
@@ -505,8 +563,40 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 	}
 }
 
-//virtual
-void LLPanelPlaces::changed(U32 mask)
+void LLPanelPlaces::changedParcelSelection()
+{
+	if (!mPlaceInfo)
+		return;
+
+	mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
+	LLParcel* parcel = mParcel->getParcel();
+	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
+	if (!region || !parcel)
+		return;
+
+	// If agent is inside the selected parcel show agent's region<X, Y, Z>,
+	// otherwise show region<X, Y, Z> of agent's selection point.
+	if (region == gAgent.getRegion() &&
+		parcel->getLocalID() == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID())
+	{
+		mPosGlobal = gAgent.getPositionGlobal();
+	}
+	else
+	{
+		LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal;
+		if (!pos_global.isExactlyZero())
+		{
+			mPosGlobal = pos_global;
+		}
+	}
+
+	mPlaceInfo->resetLocation();
+	mPlaceInfo->displaySelectedParcelInfo(parcel, region, mPosGlobal);
+
+	updateVerbs();
+}
+
+void LLPanelPlaces::changedInventory(U32 mask)
 {
 	if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))
 		return;
@@ -541,7 +631,7 @@ void LLPanelPlaces::changed(U32 mask)
 
 	// we don't need to monitor inventory changes anymore,
 	// so remove the observer
-	gInventory.removeObserver(this);
+	gInventory.removeObserver(mInventoryObserver);
 }
 
 void LLPanelPlaces::onAgentParcelChange()
@@ -549,11 +639,7 @@ void LLPanelPlaces::onAgentParcelChange()
 	if (!mPlaceInfo)
 		return;
 
-	if (mPlaceInfo->getVisible() && mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
-	{
-		onOpen(LLSD().insert("type", mPlaceInfoType));
-	}
-	else if (mPlaceInfo->isMediaPanelVisible())
+	if (mPlaceInfo->isMediaPanelVisible())
 	{
 		onOpen(LLSD().insert("type", AGENT_INFO_TYPE));
 	}
@@ -800,15 +886,6 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
 	}
 }
 
-static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global)
-{
-	F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
-	F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
-
-	LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
-	return pos_local;
-}
-
 static void onSLURLBuilt(std::string& slurl)
 {
 	LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 057c4302301..54bc2b9003b 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -32,33 +32,35 @@
 #ifndef LL_LLPANELPLACES_H
 #define LL_LLPANELPLACES_H
 
-#include "lltimer.h"
-
 #include "llpanel.h"
 
-#include "llinventory.h"
-
-#include "llinventorymodel.h"
-#include "llpanelplaceinfo.h"
-
 class LLInventoryItem;
+class LLFilterEditor;
 class LLLandmark;
+class LLPanelPlaceInfo;
 class LLPanelPlacesTab;
-class LLFilterEditor;
+class LLParcelSelection;
+class LLPlacesInventoryObserver;
+class LLPlacesParcelObserver;
 class LLTabContainer;
+class LLToggleableMenu;
 
 typedef std::pair<LLUUID, std::string>	folder_pair_t;
 
-class LLPanelPlaces : public LLPanel, LLInventoryObserver
+class LLPanelPlaces : public LLPanel
 {
 public:
 	LLPanelPlaces();
 	virtual ~LLPanelPlaces();
 
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void changed(U32 mask);
 	/*virtual*/ void onOpen(const LLSD& key);
 
+	// Called on parcel selection change to update place information.
+	void changedParcelSelection();
+	// Called on agent inventory change to find out when inventory gets usable.
+	void changedInventory(U32 mask);
+
 	void setItem(LLInventoryItem* item);
 
 private:
@@ -96,9 +98,12 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 	LLButton*					mShareBtn;
 	LLButton*					mOverflowBtn;
 
+	LLPlacesInventoryObserver*	mInventoryObserver;
+	LLPlacesParcelObserver*		mParcelObserver;
+
 	// Pointer to a landmark item or to a linked landmark
 	LLPointer<LLInventoryItem>	mItem;
-	
+
 	// Absolute position of the location for teleport, may not
 	// be available (hence zero)
 	LLVector3d					mPosGlobal;
@@ -118,11 +123,13 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 
 	// List of folders to choose from when creating a landmark
 	folder_vec_t				mLandmarkFoldersCache;
-	
+
 	// If root view width or height is changed
 	// the pop-up menu must be updated
 	S32							mRootViewWidth;
 	S32							mRootViewHeight;
+
+	LLSafeHandle<LLParcelSelection>	mParcel;
 };
 
 #endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 0c16cea0049..04abe36878c 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -43,7 +43,8 @@ bool LLRecentPeople::add(const LLUUID& id)
 	if (contains(id) || id == gAgent.getID())
 		return false;
 
-	mList.insert(id);
+	LLDate date_added = LLDate::now();
+	mList.insert(std::make_pair(id, date_added));
 	mChangedSignal();
 	return true;
 }
@@ -56,8 +57,8 @@ bool LLRecentPeople::contains(const LLUUID& id) const
 void LLRecentPeople::get(std::vector<LLUUID>& result) const
 {
 	result.clear();
-	for (std::set<LLUUID>::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
-		result.push_back(*pos);
+	for (recent_people_t::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
+		result.push_back((*pos).first);
 }
 
 // virtual
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 40ac80e8bce..c18116b4e5d 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -41,6 +41,8 @@
 #include <set>
 #include <boost/signals2.hpp>
 
+class LLDate;
+
 /**
  * List of people the agent recently interacted with.
  * 
@@ -62,7 +64,7 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
 	 * Add specified avatar to the list if it's not there already.
 	 *
 	 * @param id avatar to add.
-	 * @return false if the avatar is in the list already, true otherwisr
+	 * @return false if the avatar is in the list already, true otherwise
 	 */
 	bool add(const LLUUID& id);
 
@@ -94,7 +96,8 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
 	/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 
 private:
-	std::set<LLUUID>	mList;
+	typedef std::map<LLUUID, LLDate> recent_people_t;
+	recent_people_t		mList;
 	signal_t			mChangedSignal;
 };
 
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index 33efae50ae8..0b7621daa50 100644
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
@@ -83,6 +83,7 @@ LLSearchComboBox::LLSearchComboBox(const Params&p)
 	mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL);
 	setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
 	setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2));
+	mSearchButton->setCommitCallback(boost::bind(&LLSearchComboBox::onTextCommit, this, _2));
 }
 
 void LLSearchComboBox::rebuildSearchHistory(const std::string& filter)
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index 913e46e05e0..15d54d8b3b7 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -55,6 +55,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif
 	mUserName->setValue(p.from);
 	mTime->setValue(p.time);
 	mSessionID = p.session_id;
+	mNotification = p.notification;
 
 	mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
 
@@ -75,7 +76,9 @@ LLToastIMPanel::~LLToastIMPanel()
 //--------------------------------------------------------------------------
 void LLToastIMPanel::onClickReplyBtn()
 {
-	LLIMFloater::toggle(mSessionID);
+	LLSD response = mNotification->getResponseTemplate();
+	response["respondbutton"] = true;
+	mNotification->respond(response);
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 11f489c12fc..b51ce233644 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -63,6 +63,7 @@ class LLToastIMPanel: public LLToastPanel
 
 	void onClickReplyBtn();
 
+	LLNotificationPtr	mNotification;
 	LLUUID				mSessionID;
 	LLAvatarIconCtrl*	mAvatar;
 	LLTextBox*			mUserName;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac3defef01a..12d5687877d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -100,7 +100,6 @@
 #include "llfloaterdirectory.h"
 #include "llfloaterchatterbox.h"
 #include "llfloaterfonttest.h"
-#include "llfloatergesture.h"
 #include "llfloatergodtools.h"
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
@@ -183,7 +182,6 @@
 #include "lluuid.h"
 #include "llviewercamera.h"
 #include "llviewergenericmessage.h"
-#include "llviewergesture.h"
 #include "llviewertexturelist.h"	// gTextureList
 #include "llviewerinventory.h"
 #include "llviewermenufile.h"	// init_menu_file()
@@ -210,6 +208,7 @@
 #include "llwlparammanager.h"
 #include "llwaterparammanager.h"
 #include "llfloaternotificationsconsole.h"
+#include "llfloatercamera.h"
 
 #include "lltexlayer.h"
 #include "llappearancemgr.h"
@@ -3768,6 +3767,7 @@ void handle_reset_view()
 	else
 	{
 		reset_view_final( TRUE );
+		LLFloaterCamera::resetCameraMode();
 	}
 }
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e5d0e3ebb2f..f7fbe96aa7e 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2364,7 +2364,7 @@ void LLViewerWindow::updateUI()
 
 	updateWorldViewRect();
 
-	//updateBottomTrayRect();
+	updateBottomTrayRect();
 
 	LLView::sMouseHandlerMessage.clear();
 
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 37c6cbf3914..e94ca1b30b6 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -25,6 +25,8 @@
         Fetched
     </floater.string>
     <filter_editor
+     search_button_visible="false"
+     text_pad_left="12"
      follows="left|top|right"
      height="16"
      label="Type here to search"
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index d76ea398d51..76b2e5c8111 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <floater 
- background_opaque="false"
- background_visible="true" 
  bevel_style="in"
- bg_alpha_color="0.0 0.0 0.0 0.0"
  left="0"
  top="0" 
  follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 3de3365539c..f211ae0ad62 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -1,65 +1,89 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- All our XML is utf-8 encoded. -->
-
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
-	name="avatar_list_item"
-	title="avatar_list_item"
-  visible="true"
-	width="314"
-	height="30"
-  left="0"
-  top="100"
-  follows="bottom|right|left"
-  min_width="150" 
-  max_height="30" 
-  
-  background_opaque="false"
-  background_visible="true"
-  bevel_style="in"
-  bg_alpha_color="0.3 0.3 0.3 1.0">
-  
-  <avatar_icon
-    bottom="5" left="5" width="20" height="20" follows="top|left"
-    color="1 1 1 1" enabled="true" image_name="smile.png"
-    mouse_opaque="true" name="avatar_icon"
-  />
-  
-  <text
-    bottom="4" left="35" width="160" height="20" follows="right|left"
-    font="SansSerifBigBold" text_color="white"
-    mouse_opaque="true" name="user_name" >
-    Boris Linden
-  </text>  
-  
-  <text
-    bottom="3" left="190" width="40" height="20" follows="right"
-    font="SansSerif" text_color="0.5 0.5 0.5 1.0"
-    mouse_opaque="true" name="user_status" >
-    Away
-  </text>
-
-  <icon
-    bottom="5" left="230" width="20" height="20" follows="right"
-    color="1 1 1 1" enabled="true" image_name="speaking_indicator.tga"
-    mouse_opaque="true" name="locator"
-  />
-  
-  <button
-    bottom="5" left="260" width="20" height="20" follows="right"
-    name="info_btn" label=""
-    image_unselected="avatar_info_btn.tga" image_disabled="avatar_info_btn.tga"
-    image_selected="avatar_info_btn_active.tga" image_hover_selected="avatar_info_btn_active.tga"
-    image_disabled_selected="avatar_info_btn.tga" font="SansSerifBigBold"
-  />
-  
-  <button
-    bottom="5" left="290" width="20" height="20" follows="right"
-    name="profile_btn" label=""
-    image_unselected="profile_chevron_btn.tga" image_disabled="profile_chevron_btn.tga"
-    image_selected="profile_chevron_btn_active.tga" image_hover_selected="profile_chevron_btn_active.tga"
-    image_disabled_selected="profile_chevron_btn.tga" font="SansSerifBigBold"
-  />
-
-
-
-</panel> 
+ follows="top|right|left"
+ height="24"
+ layout="topleft"
+ left="0"
+ name="avatar_list_item"
+ top="0"
+ width="320">
+    <icon
+     follows="top|right|left" 
+     height="24"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="320" />
+    <icon
+     height="24"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="320" />
+    <avatar_icon
+     follows="top|left"
+     height="20"
+     image_name="smile.png"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     width="20" />
+    <text
+     follows="left|right"
+     font="SansSerifBigBold"
+     height="20"
+     layout="topleft"
+     left_pad="5"
+     name="avatar_name"
+     text_color="white"
+     top="4"
+     use_ellipses="true" 
+     value="Unknown"
+     width="180" />
+    <text
+     follows="right"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     left_pad="10"
+     name="avatar_status"
+     text_color="0.5 0.5 0.5 1"
+     value="Away"
+     width="50" />
+    <output_monitor
+     auto_update="true"
+     follows="right"
+     draw_border="false"
+     halign="left"
+     height="16"
+     layout="topleft"
+     left_pad="3"
+     mouse_opaque="true"
+     name="speaking_indicator"
+     top="4"
+     visible="true"
+     width="20" />
+    <button
+     follows="right"
+     font="SansSerifBigBold"
+     height="18"
+     image_disabled="Info"
+     image_disabled_selected="Info"
+     image_hover_selected="Info"
+     image_selected="Info"
+     image_unselected="Info"
+     layout="topleft"
+     left_pad="2"
+     name="info_btn"
+     picture_style="true"
+     top="2"
+     width="18" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 9ae165cbb9c..7b8bd8b3373 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -185,7 +185,7 @@
 Select multiple Members by holding the Ctrl key and
 clicking on their names.
             </panel.string>
-         <search_editor
+         <filter_editor
          layout="topleft"
          top="10"
          left="4"
@@ -193,17 +193,9 @@ clicking on their names.
          height="20"
          follows="left|top|right"
          max_length="250"
-         label="Filter People"
+         label="Filter Members"
          name="filter_input"
-         font="SansSerif"
-         background_image="TextField_Search_Off"
-         text_pad_left="10"
-         text_color="black">
-           <search_button label=""
-           top_pad="4"
-           left_pad="6" 
-               />
-         </search_editor>
+         font="SansSerif" />
             <!--<line_editor
              border_style="line"
              border_thickness="1"
@@ -318,7 +310,7 @@ including the Everyone and Owner Roles.
              name="power_partial_icon">
                 checkbox_enabled_false.tga
             </panel.string>
-            <search_editor
+            <filter_editor
             layout="topleft"
             top="10"
             left="4"
@@ -328,15 +320,7 @@ including the Everyone and Owner Roles.
             max_length="250"
             label="Filter Roles"
             name="filter_input"
-            font="SansSerif"
-            background_image="TextField_Search_Off"
-            text_pad_left="10"
-            text_color="black">
-                 <search_button label=""
-                 top_pad="4"
-                 left_pad="6" 
-                    />
-            </search_editor>
+            font="SansSerif" />
             <!--<line_editor
              border_style="line"
              border_thickness="1"
@@ -426,7 +410,7 @@ including the Everyone and Owner Roles.
                 Abilities allow Members in Roles to do specific
 things in this group. There&apos;s a broad variety of Abilities.
             </panel.string>
-            <search_editor
+            <filter_editor
             layout="topleft"
             top="10"
             left="4"
@@ -436,15 +420,7 @@ things in this group. There&apos;s a broad variety of Abilities.
             max_length="250"
             label="Filter Abilities"
             name="filter_input"
-            font="SansSerif"
-            background_image="TextField_Search_Off"
-            text_pad_left="10"
-            text_color="black">
-                 <search_button label=""
-                 top_pad="4"
-                 left_pad="6" 
-                  />
-            </search_editor>
+            font="SansSerif" />
             <!--<line_editor
              border_style="line"
              border_thickness="1"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 0af42bfc745..3642b0fec1c 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -31,7 +31,6 @@
      name="groups_filter_label"
      value="Filter Groups" />
     <filter_editor
-     background_image="TextField_Search_Off"
      follows="left|top|right"
      font="SansSerif"
      height="23"
@@ -40,21 +39,8 @@
      max_length="270"
      name="filter_input"
      text_color="black"
-     text_pad_left="26"
      top="3"
      width="256" />
-    <button
-     follows="left|top|right"
-     height="13"
-     image_selected="Search"
-     image_unselected="Search"
-     layout="topleft"
-     left="20"
-     name="people_search"
-     picture_style="true"
-     scale_image="false"
-     top="8"
-     width="13" />
     <tab_container
      follows="left|top|right|bottom"
      height="326"
@@ -303,7 +289,8 @@
          layout="topleft"
          name="recent_panel"
          width="285">
-            <avatar_list
+            <avatar_list_tmp
+             color="DkGray2" 
              follows="left|top|right|bottom"
              height="357"
              layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index bff28718a7a..b379ad22761 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -16,7 +16,6 @@
      name="teleport_history_tab_title"
      value="Teleport History" />
     <filter_editor
-     background_image="TextField_Search_Off"
      follows="left|top|right"
      font="SansSerif"
      height="23"
@@ -24,22 +23,8 @@
      layout="topleft"
      left="15"
      name="Filter"
-     text_color="black"
-     text_pad_left="26"
      top="3"
      width="256" />
-    <button
-     follows="left|top|right"
-     height="13"
-     image_selected="Search"
-     image_unselected="Search"
-     layout="topleft"
-     left="20"
-     name="landmark_search"
-     picture_style="true"
-     scale_image="false"
-     top="8"
-     width="13" />
     <tab_container
      follows="all"
      height="326"
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 441caffa284..01fd84e09de 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -11,8 +11,6 @@
   left="100"
   top="500"
   follows="right|bottom" 
-  background_opaque="true"
-  background_visible="true"
   bevel_style="in"
   can_minimize="false"
   can_tear_off="false"
@@ -20,7 +18,7 @@
   can_drag_on_left="false"
   can_close="false"
   can_dock="false"  
-  bg_alpha_color="0.3 0.3 0.3 1.0">
+  >
 
   <text
    visible="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index faed615bdd9..4206b87c2b3 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1818,6 +1818,7 @@ this texture in your inventory
 	<string name="AnimFlagStart" value=" Start Animation :   " />
 	<string name="Wave"          value=" Wave " />
 	<string name="HelloAvatar"   value=" Hello, avatar! " />
+	<string name="ViewAllGestures"  value="  View All >>" />
 				
 	<!-- inventory filter -->
     <!-- use value="" because they have preceding spaces -->
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index a34b0054481..ada258fbece 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -1,8 +1,20 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<filter_editor select_on_focus="true"
-               background_image_disabled="TextField_Search_Disabled"
-               background_image_focused="TextField_Search_Active">
-  <clear_filter_button label="" 
-                       image_unselected="Icon_Close_Foreground"
-                       image_selected="Icon_Close_Press" />
+<filter_editor
+  clear_button_visible="true"
+  search_button_visible="true"
+  text_pad_left="4" 
+  select_on_focus="true"
+  background_image="TextField_Search_Off"
+  background_image_disabled="TextField_Search_Disabled"
+  background_image_focused="TextField_Search_Active" >
+  <search_button label=""
+    top_pad="4"
+    left_pad="4" 
+    width="13"
+    height="13" 
+	  image_unselected="Search"
+	  image_selected="Search" />
+  <clear_button label=""
+   image_unselected="Icon_Close_Foreground"
+   image_selected="Icon_Close_Press" />
 </filter_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
new file mode 100644
index 00000000000..24d072a5737
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<flat_list_view
+ allow_select="true"
+ item_pad="5"
+ keep_one_selected="true"
+ multi_select="false"
+ opaque="true" />
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index 8643f919ec5..f482ff3b894 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <search_editor
   clear_button_visible="false"
+  search_button_visible="true"
   text_pad_left="4" 
   select_on_focus="true"
   background_image="TextField_Search_Off"
@@ -13,7 +14,7 @@
     height="13" 
 	  image_unselected="Search"
 	  image_selected="Search" />
-  <clear_button label="" 
+  <clear_button label=""
    image_unselected="Icon_Close_Foreground"
    image_selected="Icon_Close_Press" />
 </search_editor>
-- 
GitLab