diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index e12da97f3bce3a09df42205d4b70503c3a5f1f22..046118cf75b2e066de006c6a825a94bf45ba51f3 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -38,6 +38,7 @@
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "lliconctrl.h"
+#include "llsidetray.h"
 #include "lltabcontainer.h"
 #include "lltexturectrl.h"
 
@@ -70,6 +71,45 @@ void LLPanelMe::onOpen(const LLSD& key)
 	LLPanelProfile::onOpen(key);
 }
 
+void LLPanelMe::notifyChildren(const LLSD& info)
+{
+	if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
+	{
+		// Implement task panel tri-state behavior.
+		//
+		// When the button of an active open task panel is clicked, side tray
+		// calls notifyChildren() on the panel, passing task-panel-action=>handle-tri-state as an argument.
+		// The task panel is supposed to handle this by reverting to the default view,
+		// i.e. closing any dependent panels like "pick info" or "profile edit".
+
+		bool on_default_view = true;
+
+		const LLRect& task_panel_rect = getRect();
+		for (LLView* child = getFirstChild(); child; child = findNextSibling(child))
+		{
+			LLPanel* panel = dynamic_cast<LLPanel*>(child);
+			if (!panel)
+				continue;
+
+			// *HACK: implement panel stack instead (e.g. me->pick_info->pick_edit).
+			if (panel->getRect().getWidth()  == task_panel_rect.getWidth()  &&
+				panel->getRect().getHeight() == task_panel_rect.getHeight() &&
+				panel->getVisible())
+			{
+				panel->setVisible(FALSE);
+				on_default_view = false;
+			}
+		}
+		
+		if (on_default_view)
+			LLSideTray::getInstance()->collapseSideBar();
+
+		return; // this notification is only supposed to be handled by task panels 
+	}
+
+	LLPanel::notifyChildren(info);
+}
+
 void LLPanelMe::buildEditPanel()
 {
 	if (NULL == mEditPanel)
@@ -84,8 +124,7 @@ void LLPanelMe::buildEditPanel()
 void LLPanelMe::onEditProfileClicked()
 {
 	buildEditPanel();
-	togglePanel(mEditPanel);
-	mEditPanel->onOpen(getAvatarId());
+	togglePanel(mEditPanel, getAvatarId()); // open
 }
 
 void LLPanelMe::onEditAppearanceClicked()
@@ -108,13 +147,13 @@ void LLPanelMe::onSaveChangesClicked()
 	data.allow_publish = mEditPanel->childGetValue("show_in_search_checkbox");
 
 	LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&data);
-	togglePanel(mEditPanel);
+	togglePanel(mEditPanel); // close
 	onOpen(getAvatarId());
 }
 
 void LLPanelMe::onCancelClicked()
 {
-	togglePanel(mEditPanel);
+	togglePanel(mEditPanel); // close
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h
index e16532a445c8b736ab4d476179c71d8a79f71050..17d367132edb82b6d7e2f768a4ffb190705cf1ae 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llpanelme.h
@@ -54,6 +54,7 @@ class LLPanelMe : public LLPanelProfile
 	LLPanelMe();
 
 	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void notifyChildren(const LLSD& info);
 
 	/*virtual*/ BOOL postBuild();
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 4dc88725573273b3e7655fa4843f2f04c0cfd916..2ccd10a06578589e91d72ce51138b387c996a35d 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -56,6 +56,8 @@
 #include "llgrouplist.h"
 #include "llinventoryobserver.h"
 #include "llpanelpeoplemenus.h"
+#include "llsidetray.h"
+#include "llsidetraypanelcontainer.h"
 #include "llrecentpeople.h"
 #include "llviewercontrol.h"		// for gSavedSettings
 #include "llviewermenu.h"			// for gMenuHolder
@@ -1263,6 +1265,31 @@ void	LLPanelPeople::onOpen(const LLSD& key)
 		reSelectedCurrentTab();
 }
 
+void LLPanelPeople::notifyChildren(const LLSD& info)
+{
+	if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
+	{
+		LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+		if (!container)
+		{
+			llwarns << "Cannot find People panel container" << llendl;
+			return;
+		}
+
+		if (container->getCurrentPanelIndex() > 0) 
+		{
+			// if not on the default panel, switch to it
+			container->onOpen(LLSD().insert(LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME, getName()));
+		}
+		else
+			LLSideTray::getInstance()->collapseSideBar();
+
+		return; // this notification is only supposed to be handled by task panels
+	}
+
+	LLPanel::notifyChildren(info);
+}
+
 void LLPanelPeople::showAccordion(const std::string name, bool show)
 {
 	if(name.empty())
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index a369bcd3e2ad6bf64c65507b7f5db2031d6a0c2f..d9dd76f3acd9645e341dc26c61a6ec454bbb3a28 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -50,8 +50,8 @@ class LLPanelPeople : public LLPanel
 	virtual ~LLPanelPeople();
 
 	/*virtual*/ BOOL 	postBuild();
-
-	virtual void	onOpen(const LLSD& key);
+	/*virtual*/ void	onOpen(const LLSD& key);
+	/*virtual*/ void	notifyChildren(const LLSD& info);
 
 	// internals
 	class Updater;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 02f45c1b487fdd05c2b420a5f838067b9e562d43..4d152a13f306c516214156a1b7bfa22c51340710 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -158,28 +158,14 @@ void LLPanelProfile::onOpen(const LLSD& key)
 }
 
 //*TODO redo panel toggling
-void LLPanelProfile::togglePanel(LLPanel* panel)
+void LLPanelProfile::togglePanel(LLPanel* panel, const LLSD& key)
 {
 	// TRUE - we need to open/expand "panel"
 	bool expand = getChildList()->front() != panel;  // mTabCtrl->getVisible();
 
 	if (expand)
 	{
-		if (panel->getParent() != this)
-		{
-			addChild(panel);
-		}
-		else
-		{
-			sendChildToFront(panel);
-		}
-
-		panel->setVisible(TRUE);
-
-		LLRect new_rect = getRect();
-		panel->reshape(new_rect.getWidth(), new_rect.getHeight());
-		new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
-		panel->setRect(new_rect);
+		openPanel(panel, key);
 	}
 	else 
 	{
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index e216eb70f26dc298ac0bcf62a2290c4723bc3c23..067beb248b9f27054cb8f8a82c3888e8fd181ae1 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -51,7 +51,7 @@ class LLPanelProfile : public LLPanel
 
 	/*virtual*/ void onOpen(const LLSD& key);
 
-	virtual void togglePanel(LLPanel*);
+	virtual void togglePanel(LLPanel*, const LLSD& key = LLSD());
 
 	virtual void openPanel(LLPanel* panel, const LLSD& params);
 
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index d4ab5013f9592dc4a54e667375d53441e7f6e903..08aea8cfd834ccf31a864d708667bbb2156587cf 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -193,8 +193,10 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&
 	getChild<LLTextBox>("user_name", FALSE)->setValue(first_name + " " + last_name);
 }
 
-void LLPanelProfileView::togglePanel(LLPanel* panel)
+void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key)
 {
+	// *TODO: unused method?
+
 	LLPanelProfile::togglePanel(panel);
 	if(FALSE == panel->getVisible())
 	{
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 45c2fc116e7ff4ec0f8f8b2bbb5c12a793f9b114..5dc617d4a04e568b04a3f81114f8e4c2c2f59a6a 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -64,7 +64,7 @@ class LLPanelProfileView : public LLPanelProfile
 	
 	/*virtual*/ BOOL postBuild();
 
-	/*virtual*/ void togglePanel(LLPanel* panel);
+	/*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD());
 
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
 						   BOOL drop, EDragAndDropType cargo_type,
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 7711f3c7330bd09a16c972f7d9c39b9a5b3c537a..0b832a8239b2de4dc74ea1be2f40b1476766622a 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -435,35 +435,16 @@ void		LLSideTray::processTriState ()
 		expandSideBar();
 	else
 	{
-		//!!!!!!!!!!!!!!!!!
-		//** HARDCODED!!!!!
-		//!!!!!!!!!!!!!!!!!
-
-		//there is no common way to determine "default" panel for tab
-		//so default panels for now will be hardcoded
-
-		//hardcoded for people tab and profile tab
-
-		/*if(mActiveTab == getTab("sidebar_people"))
-		{
-			LLSideTrayPanelContainer* container = findChild<LLSideTrayPanelContainer>("panel_container");
-			if(container && container->getCurrentPanelIndex()>0)
-			{
-				container->onOpen(LLSD().insert("sub_panel_name","panel_people"));
-			}
-			else
-				collapseSideBar();
-		}
-		else if(mActiveTab == getTab("sidebar_me"))
-		{
-			LLTabContainer* tab_container = findChild<LLTabContainer>("tabs");
-			if(tab_container && tab_container->getCurrentPanelIndex()>0)
-				tab_container->selectFirstTab();
-			else
-				collapseSideBar();
-		}
-		else*/
-			collapseSideBar();
+#if 0 // *TODO: EXT-2092
+		
+		// Tell the active task panel to switch to its default view
+		// or collapse side tray if already on the default view.
+		LLSD info;
+		info["task-panel-action"] = "handle-tri-state";
+		mActiveTab->notifyChildren(info);
+#else
+		collapseSideBar();
+#endif
 	}
 }