diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index d836a5f4cd8aa6cc445ab126014132359b56fbcc..d738b101308211c75fd749f9623e332d0e0b8667 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -162,7 +162,9 @@ bool LLDockControl::isDockVisible()
 			{
 			case LEFT: // to keep compiler happy
 				break;
+			case BOTTOM:
 			case TOP:
+			{
 				// check is dock inside parent rect
 				LLRect dockParentRect =
 						mDockWidget->getParent()->calcScreenRect();
@@ -173,6 +175,9 @@ bool LLDockControl::isDockVisible()
 				}
 				break;
 			}
+			default:
+				break;
+			}
 		}
 	}
 
@@ -254,6 +259,42 @@ void LLDockControl::moveDockable()
 		}
 		mDockTongueY = dockRect.mTop;
 
+		break;
+	case BOTTOM:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+		y = dockRect.mBottom;
+		// unique docking used with dock tongue, so add tongue height o the Y coordinate
+		if (use_tongue)
+		{
+			y -= mDockTongue->getHeight();
+		}
+
+		// check is dockable inside root view rect
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
+
+		// calculate dock tongue position
+		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		if (dockRect.getCenterX() < dockParentRect.mLeft)
+		{
+			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+		}
+		else if (dockRect.getCenterX() > dockParentRect.mRight)
+		{
+			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+		}
+		else
+		{
+			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+		}
+		mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
+
 		break;
 	}
 
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 550955c4c537484ad5a0db3c44e2bd25bfb78749..a5caf680016505ea7b1ac2b3ba913dff3995db81 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -47,8 +47,9 @@ class LLDockControl
 public:
 	enum DocAt
 	{
-		TOP
-		,LEFT
+		TOP,
+		LEFT,
+		BOTTOM
 	};
 
 public:
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 478e270c9862a6d12fcdd9045460b1d5dcfc6535..ac4811210b8475bac640a6d823626094d30463d8 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1388,6 +1388,8 @@ void LLScrollListCtrl::drawItems()
 
 	LLGLSUIDefault gls_ui;
 	
+	F32 alpha = getDrawContext().mAlpha;
+
 	{
 		LLLocalClipRect clip(mItemListRect);
 
@@ -1463,7 +1465,7 @@ void LLScrollListCtrl::drawItems()
 					bg_color = mBgReadOnlyColor.get();
 				}
 
-				item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding);
+				item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
 
 				cur_y -= mLineHeight;
 			}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cd7c0020966c28b6b497fc118b15a328612ad08d..6242783717de786a5ec81020c6a6f63d78180dac 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -182,7 +182,6 @@ set(viewer_SOURCE_FILES
     llfloatermediasettings.cpp
     llfloatermemleak.cpp
     llfloaternamedesc.cpp
-    llfloaternearbymedia.cpp
     llfloaternotificationsconsole.cpp
     llfloateropenobject.cpp
     llfloaterparcel.cpp
@@ -323,6 +322,7 @@ set(viewer_SOURCE_FILES
     llpanelmediasettingspermissions.cpp
     llpanelmediasettingssecurity.cpp
     llpanelme.cpp
+    llpanelnearbymedia.cpp
     llpanelobject.cpp
     llpanelobjectinventory.cpp
     llpaneloutfitsinventory.cpp
@@ -682,7 +682,6 @@ set(viewer_HEADER_FILES
     llfloatermediasettings.h
     llfloatermemleak.h
     llfloaternamedesc.h
-    llfloaternearbymedia.h
     llfloaternotificationsconsole.h
     llfloateropenobject.h
     llfloaterparcel.h
@@ -818,6 +817,7 @@ set(viewer_HEADER_FILES
     llpanelmediasettingspermissions.h
     llpanelmediasettingssecurity.h
     llpanelme.h
+    llpanelnearbymedia.h
     llpanelobject.h
     llpanelobjectinventory.h
     llpaneloutfitsinventory.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d0c2f3cb34716a29e05b50314f4514f8ac21da67..779c16ead1145db47141e072ff96ecc68f99946c 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4578,6 +4578,50 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+  <key>MediaShowOnOthers</key>
+  <map>
+    <key>Comment</key>
+    <string>Whether or not to show media on other avatars</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
+  <key>MediaShowOutsideParcel</key>
+  <map>
+    <key>Comment</key>
+    <string>Whether or not to show media from outside the current parcel</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>MediaShowWithinParcel</key>
+  <map>
+    <key>Comment</key>
+    <string>Whether or not to show media within the current parcel</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
+  <key>MediaTentativeAutoPlay</key>
+  <map>
+    <key>Comment</key>
+    <string>This is a tentative flag that may be temporarily set off by the user, until she teleports</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
   <key>MemoryLogFrequency</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4da194a20aa8d2460da093cf23a0f3cc6d960dd
--- /dev/null
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -0,0 +1,864 @@
+/** 
+ * @file llpanelnearbymedia.cpp
+ * @brief Management interface for muting and controlling nearby media
+ *
+ * $LicenseInfo:firstyear=2005&license=viewergpl$
+ * 
+ * Copyright (c) 2005-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 "llviewerprecompiledheaders.h"
+
+#include "llpanelnearbymedia.h"
+
+#include "llaudioengine.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
+#include "llsliderctrl.h"
+#include "llagent.h"
+#include "llagentui.h"
+#include "llbutton.h"
+#include "lltextbox.h"
+#include "llviewermedia.h"
+#include "llviewerparcelmedia.h"
+#include "llviewerregion.h"
+#include "llviewermediafocus.h"
+#include "llviewerparcelmgr.h"
+#include "llparcel.h"
+#include "llpluginclassmedia.h"
+#include "llvovolume.h"
+#include "llstatusbar.h"
+#include "llsdutil.h"
+
+#include "llfloaterreg.h"
+#include "llfloaterpreference.h" // for the gear icon
+#include "lltabcontainer.h"
+
+#include <stringize.h>
+
+extern LLControlGroup gSavedSettings;
+
+// Ugh, isInternetStreamPlaying() returns not a bool, but an *int*, with
+// 0 = stopped, 1 = playing, 2 = paused.
+static const int PARCEL_AUDIO_STOPPED = 0;
+static const int PARCEL_AUDIO_PLAYING = 1;
+static const int PARCEL_AUDIO_PAUSED = 2;
+
+//
+// LLPanelNearByMedia
+//
+
+LLPanelNearByMedia::LLPanelNearByMedia()
+:	mMediaList(NULL),
+	  mEnableAllCtrl(NULL),
+	  mEnableParcelMediaCtrl(NULL),	  
+	  mAllMediaDisabled(false),
+	  mDebugInfoVisible(false)
+{
+	mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING);
+
+	mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll",		boost::bind(&LLPanelNearByMedia::onClickEnableAll, this));
+	mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll",		boost::bind(&LLPanelNearByMedia::onClickDisableAll, this));
+	mCommitCallbackRegistrar.add("MediaListCtrl.GoMediaPrefs", boost::bind(&LLPanelNearByMedia::onAdvancedButtonClick, this));
+	mCommitCallbackRegistrar.add("MediaListCtrl.MoreLess", boost::bind(&LLPanelNearByMedia::onMoreLess, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.ParcelMediaVolume",		boost::bind(&LLPanelNearByMedia::onParcelMediaVolumeSlider, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.MuteParcelMedia",		boost::bind(&LLPanelNearByMedia::onClickMuteParcelMedia, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.EnableParcelMedia",		boost::bind(&LLPanelNearByMedia::onClickEnableParcelMedia, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.DisableParcelMedia",		boost::bind(&LLPanelNearByMedia::onClickDisableParcelMedia, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.Play",		boost::bind(&LLPanelNearByMedia::onClickParcelMediaPlay, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.Stop",		boost::bind(&LLPanelNearByMedia::onClickParcelMediaStop, this));
+	mCommitCallbackRegistrar.add("ParcelMediaCtrl.Pause",		boost::bind(&LLPanelNearByMedia::onClickParcelMediaPause, this));
+	mCommitCallbackRegistrar.add("ParcelAudioCtrl.Play",		boost::bind(&LLPanelNearByMedia::onClickParcelAudioPlay, this));
+	mCommitCallbackRegistrar.add("ParcelAudioCtrl.Stop",		boost::bind(&LLPanelNearByMedia::onClickParcelAudioStop, this));
+	mCommitCallbackRegistrar.add("ParcelAudioCtrl.Pause",		boost::bind(&LLPanelNearByMedia::onClickParcelAudioPause, this));
+	LLUICtrlFactory::instance().buildPanel(this, "panel_nearby_media.xml");
+}
+
+LLPanelNearByMedia::~LLPanelNearByMedia()
+{
+}
+
+BOOL LLPanelNearByMedia::postBuild()
+{
+	LLPanel::postBuild();
+
+	mNearbyMediaPanel = getChild<LLUICtrl>("nearby_media_panel");
+	mMediaList = getChild<LLScrollListCtrl>("media_list");
+	mEnableAllCtrl = getChild<LLUICtrl>("all_nearby_media_enable_btn");
+	mDisableAllCtrl = getChild<LLUICtrl>("all_nearby_media_disable_btn");
+	mParcelMediaVolumeSlider = getChild<LLSliderCtrl>("parcel_media_volume");
+	mParcelMediaMuteCtrl = getChild<LLButton>("parcel_media_mute");
+	mEnableParcelMediaCtrl = getChild<LLUICtrl>("parcel_media_enable_btn");
+	mDisableParcelMediaCtrl = getChild<LLUICtrl>("parcel_media_disable_btn");
+	mParcelMediaText = getChild<LLTextBox>("parcel_media_name");
+	mItemCountText = getChild<LLTextBox>("media_item_count");
+	mParcelMediaPlayCtrl = getChild<LLButton>("parcel_media_play_btn");
+	mParcelMediaPauseCtrl = getChild<LLButton>("parcel_media_pause_btn");
+	mParcelMediaCtrl = getChild<LLUICtrl>("parcel_media_ctrls");
+	mParcelAudioPlayCtrl = getChild<LLButton>("parcel_audio_play_btn");
+	mParcelAudioPauseCtrl = getChild<LLButton>("parcel_audio_pause_btn");
+	mParcelAudioCtrl = getChild<LLUICtrl>("parcel_audio_ctrls");
+	mShowCtrl = getChild<LLComboBox>("show_combo");
+	
+	mEmptyNameString = getString("empty_item_text");
+	mDefaultParcelMediaName = getString("default_parcel_media_name");
+	mPlayingString = getString("playing_suffix");
+	
+	mMediaList->setDoubleClickCallback(onZoomMedia, this);
+	mMediaList->sortByColumnIndex(PROXIMITY_COLUMN, TRUE);
+	mMediaList->sortByColumnIndex(VISIBILITY_COLUMN, FALSE);
+
+	std::string url = LLViewerParcelMedia::getURL();
+	if (!url.empty())
+	{
+		std::string name = LLViewerParcelMedia::getName();
+		mParcelMediaText->setValue(name.empty()?url:name);
+		mParcelMediaText->setToolTip(url);	
+	}
+	refreshList();
+	updateColumns();
+	
+	mOriginalHeight = getRect().getHeight();
+	mNearbyMediaPanelHeight = mNearbyMediaPanel->getRect().getHeight();
+	getChild<LLUICtrl>("more_less_btn")->setValue(false);
+	onMoreLess();
+	
+	return TRUE;
+}
+
+/*virtual*/
+void LLPanelNearByMedia::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	mHoverTimer.stop();
+	LLPanel::onMouseEnter(x,y,mask);
+}
+
+
+/*virtual*/
+void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	mHoverTimer.start();
+	LLPanel::onMouseLeave(x,y,mask);
+}
+
+/*virtual*/ 
+void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )
+{
+	if (new_visibility)	
+	{
+		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
+		gFocusMgr.setTopCtrl(this);
+	}
+	else
+	{
+		mHoverTimer.stop();
+		if (gFocusMgr.getTopCtrl() == this)
+		{
+			gFocusMgr.setTopCtrl(NULL);
+		}
+	}
+}
+
+/*virtual*/ 
+void LLPanelNearByMedia::onTopLost ()
+{
+	setVisible(FALSE);
+}
+
+
+const F32 AUTO_CLOSE_FADE_TIME_START= 4.0f;
+const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f;
+
+void LLPanelNearByMedia::draw()
+{
+	mItemCountText->setValue(llformat(getString("media_item_count_format").c_str(), mMediaList->getItemCount()));
+	
+//	refreshParcelMediaUI();
+//	refreshParcelAudioUI();
+	refreshList();
+	
+	F32 alpha = mHoverTimer.getStarted() 
+		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START, AUTO_CLOSE_FADE_TIME_END, 1.f, 0.f)
+		: 1.0f;
+	LLViewDrawContext context(alpha);
+
+	LLPanel::draw();
+
+	if (alpha == 0.f)
+	{
+		setVisible(false);
+	}
+}
+
+bool LLPanelNearByMedia::getParcelAudioAutoStart()
+{
+	return mParcelAudioAutoStart;
+}
+
+void LLPanelNearByMedia::addMediaItem(const LLUUID &id)
+{
+	if (NULL == mMediaList) return;
+	
+	// Just set up the columns -- the values will be filled in by updateMediaItem().
+	
+	LLSD row;
+	row["id"] = id;
+	
+	LLSD &columns = row["columns"];
+	
+	columns[CHECKBOX_COLUMN]["column"] = "media_checkbox_ctrl";
+	columns[CHECKBOX_COLUMN]["type"] = "checkbox";	
+	//if(mDebugInfoVisible)
+	{
+	columns[PROXIMITY_COLUMN]["column"] = "media_proximity";
+	columns[PROXIMITY_COLUMN]["value"] = "";
+		columns[VISIBILITY_COLUMN]["column"] = "media_visibility";
+		columns[VISIBILITY_COLUMN]["value"] = "";
+		columns[CLASS_COLUMN]["column"] = "media_class";
+		columns[CLASS_COLUMN]["type"] = "text";
+		columns[CLASS_COLUMN]["value"] = "";
+	}
+	columns[NAME_COLUMN]["column"] = "media_name";
+	columns[NAME_COLUMN]["type"] = "text";
+	columns[NAME_COLUMN]["value"] = "";
+	//if(mDebugInfoVisible)
+	{
+		columns[DEBUG_COLUMN]["column"] = "media_debug";
+		columns[DEBUG_COLUMN]["type"] = "text";
+		columns[DEBUG_COLUMN]["value"] = "";
+	}
+	
+	LLScrollListItem* new_item = mMediaList->addElement(row);
+	LLScrollListCheck* scroll_list_check = dynamic_cast<LLScrollListCheck*>(new_item->getColumn(CHECKBOX_COLUMN));
+	if (scroll_list_check)
+	{
+		LLCheckBoxCtrl *check = scroll_list_check->getCheckBox();
+		check->setCommitCallback(boost::bind(&LLPanelNearByMedia::onCheckItem, this, _1, id));
+	}
+}
+
+void LLPanelNearByMedia::updateMediaItem(LLScrollListItem* item, LLViewerMediaImpl* impl)
+{
+	LLScrollListCell* cell = item->getColumn(PROXIMITY_COLUMN);
+	if(cell)
+	{
+		// since we are forced to sort by text, encode sort order as string
+		// proximity of -1 means "closest"
+		S32 proximity = impl->isParcelMedia() ? -1 : impl->getProximity();
+		std::string proximity_string = STRINGIZE(proximity);
+		std::string old_proximity_string = cell->getValue().asString();
+		if(proximity_string != old_proximity_string)
+		{
+			cell->setValue(proximity_string);
+			mMediaList->setNeedsSort(true);
+		}
+	}
+	
+	cell = item->getColumn(CHECKBOX_COLUMN);
+	if(cell)
+	{
+		cell->setValue(!impl->isMediaDisabled());
+	}
+	
+	cell = item->getColumn(VISIBILITY_COLUMN);
+	if(cell)
+	{
+		S32 old_visibility = cell->getValue();
+		S32 new_visibility = (impl->hasMedia()) ? 1 : ((impl->isMediaDisabled()) ? 0 : -1);
+		cell->setValue(STRINGIZE(new_visibility));
+		if (new_visibility != old_visibility)
+		{			
+			mMediaList->setNeedsSort(true);
+		}
+	}
+		
+	S32 media_class = -1;
+	cell = item->getColumn(NAME_COLUMN);
+	if(cell)
+	{
+		std::string name;
+		std::string url;
+		std::string old_name = cell->getValue().asString();
+		
+		getNameAndUrlHelper(impl, name, url, mEmptyNameString);
+		
+		if (impl->isParcelMedia())
+		{
+			cell->setToolTip(name + " : " + url);
+			name = mDefaultParcelMediaName;
+		}
+		else {
+		cell->setToolTip(url);
+		}
+		if (impl->hasMedia()) name += " " + mPlayingString;
+		if (name != old_name)
+		{
+			cell->setValue(name);
+		}
+		
+		// *TODO: Make these font styles/colors configurable via XUI
+		LLColor4 cell_color = LLColor4::white;
+		U8 font_style = LLFontGL::NORMAL;
+		
+		// Focused
+		if (impl->hasFocus())
+		{
+			if (mDebugInfoVisible) cell_color = LLColor4::yellow;
+			media_class = MEDIA_CLASS_FOCUSED;
+		}
+		// Is attached to another avatar?
+		else if (impl->isAttachedToAnotherAvatar())
+		{
+			if (mDebugInfoVisible) cell_color = LLColor4::red;
+			media_class = MEDIA_CLASS_ON_OTHERS;
+		}
+		// Outside agent parcel
+		else if (!impl->isInAgentParcel())
+		{
+			if (mDebugInfoVisible) cell_color = LLColor4::orange;
+			media_class = MEDIA_CLASS_OUTSIDE_PARCEL;
+		}
+		else {
+			// inside parcel
+			media_class = MEDIA_CLASS_WITHIN_PARCEL;
+		}
+		if (impl->isMediaDisabled())
+		{
+			//font_style |= LLFontGL::ITALIC;
+			//cell_color = LLColor4::black;
+			// Dim it if it is disabled
+			cell_color.setAlpha(0.25);
+		}
+		// Dim it if it isn't "showing"
+		else if (!impl->hasMedia())
+		{
+			cell_color.setAlpha(0.25);
+		}
+		// Bold it if it is time-based media and it is playing
+		else if (impl->isMediaTimeBased() &&
+				 impl->isMediaPlaying())
+		{
+			if (mDebugInfoVisible) font_style |= LLFontGL::BOLD;
+		}
+		cell->setColor(cell_color);
+		LLScrollListText *text_cell = dynamic_cast<LLScrollListText*> (cell);
+		if (text_cell)
+		{
+			text_cell->setFontStyle(font_style);
+		}
+	}
+	
+	cell = item->getColumn(CLASS_COLUMN);
+	if(cell)
+	{
+		// TODO: clean this up!
+		cell->setValue(STRINGIZE(media_class));
+	}
+	
+	if(mDebugInfoVisible)
+	{
+		cell = item->getColumn(DEBUG_COLUMN);
+		if(cell)
+		{
+			std::string s;
+			
+			s += llformat("%g/", (float)impl->getInterest());
+
+			// proximity distance is actually distance squared -- display it as straight distance.
+			s += llformat("%g/", fsqrtf(impl->getProximityDistance()));
+
+//			s += llformat("%g/", (float)impl->getCPUUsage());
+//			s += llformat("%g/", (float)impl->getApproximateTextureInterest());
+			s += llformat("%g/", (float)(NULL == impl->getSomeObject()) ? 0.0 : impl->getSomeObject()->getPixelArea());
+			
+			s += LLPluginClassMedia::priorityToString(impl->getPriority());
+			
+			if(impl->hasMedia())
+			{
+				s += '@';
+			}
+			else if(impl->isPlayable())
+			{
+				s += '+';
+			}
+			else if(impl->isForcedUnloaded())
+			{
+				s += '!';
+			}
+				
+			cell->setValue(s);
+		}
+	}
+}
+
+void LLPanelNearByMedia::removeMediaItem(const LLUUID &id)
+{
+	if (NULL == mMediaList) return;
+	
+	mMediaList->deleteSingleItem(mMediaList->getItemIndex(id));
+}
+
+void LLPanelNearByMedia::refreshParcelMediaUI()
+{	
+	std::string url = LLViewerParcelMedia::getURL();
+	LLStyle::Params style_params;
+	if (url.empty())
+	{	
+		style_params.font.style = "ITALIC";
+		mParcelMediaText->setText(mDefaultParcelMediaName, style_params);
+		mEnableParcelMediaCtrl->setEnabled(false);
+		mDisableParcelMediaCtrl->setEnabled(false);
+	}
+	else {
+		std::string name = LLViewerParcelMedia::getName();
+		if (name.empty()) name = url;
+		mParcelMediaText->setText(name, style_params);
+		mParcelMediaText->setToolTip(url);
+		mEnableParcelMediaCtrl->setEnabled(true);
+		mDisableParcelMediaCtrl->setEnabled(true);
+	}
+	
+	// Set up the default play controls state
+	mParcelMediaPauseCtrl->setEnabled(false);
+	mParcelMediaPauseCtrl->setVisible(false);
+	mParcelMediaPlayCtrl->setEnabled(true);
+	mParcelMediaPlayCtrl->setVisible(true);
+	mParcelMediaCtrl->setEnabled(false);
+	
+	if (LLViewerParcelMedia::getParcelMedia())
+	{
+		if (LLViewerParcelMedia::getParcelMedia()->getMediaPlugin() &&
+			LLViewerParcelMedia::getParcelMedia()->getMediaPlugin()->pluginSupportsMediaTime())
+		{
+			mParcelMediaCtrl->setEnabled(true);
+			
+			switch(LLViewerParcelMedia::getParcelMedia()->getMediaPlugin()->getStatus())
+			{
+				case LLPluginClassMediaOwner::MEDIA_PLAYING:
+					mParcelMediaPlayCtrl->setEnabled(false);
+					mParcelMediaPlayCtrl->setVisible(false);
+					mParcelMediaPauseCtrl->setEnabled(true);
+					mParcelMediaPauseCtrl->setVisible(true);
+					break;
+				case LLPluginClassMediaOwner::MEDIA_PAUSED:
+				default:
+					// default play status is kosher
+					break;
+			}
+		}
+	}
+}
+
+void LLPanelNearByMedia::refreshParcelAudioUI()
+{	
+	bool parcel_audio_enabled = !getParcelAudioURL().empty();
+
+	mParcelAudioCtrl->setToolTip(getParcelAudioURL());
+	
+	if (gAudiop && parcel_audio_enabled)
+	{
+		mParcelAudioCtrl->setEnabled(true);
+
+		if (PARCEL_AUDIO_PLAYING == gAudiop->isInternetStreamPlaying())
+		{
+			mParcelAudioPlayCtrl->setEnabled(false);
+			mParcelAudioPlayCtrl->setVisible(false);
+			mParcelAudioPauseCtrl->setEnabled(true);
+			mParcelAudioPauseCtrl->setVisible(true);
+		}
+		else {
+			mParcelAudioPlayCtrl->setEnabled(true);
+			mParcelAudioPlayCtrl->setVisible(true);
+			mParcelAudioPauseCtrl->setEnabled(false);
+			mParcelAudioPauseCtrl->setVisible(false);
+		}
+	}
+	else {
+		mParcelAudioCtrl->setEnabled(false);
+		mParcelAudioPlayCtrl->setEnabled(true);
+		mParcelAudioPlayCtrl->setVisible(true);
+		mParcelAudioPauseCtrl->setEnabled(false);
+		mParcelAudioPauseCtrl->setVisible(false);
+	}
+}
+
+void LLPanelNearByMedia::refreshList()
+{
+	bool all_items_deleted = false;
+		
+	if(!mMediaList)
+	{
+		// None of this makes any sense if the media list isn't there.
+		return;
+	}
+	
+	// Check whether the debug column has been shown/hidden.
+	bool debug_info_visible = gSavedSettings.getBOOL("MediaPerformanceManagerDebug");
+	if(debug_info_visible != mDebugInfoVisible)
+	{
+		mDebugInfoVisible = debug_info_visible;
+
+		// Clear all items so the list gets regenerated.
+		mMediaList->deleteAllItems();
+		all_items_deleted = true;
+		
+		updateColumns();
+	}
+	
+	// Get the canonical list from LLViewerMedia
+	LLViewerMedia::impl_list impls = LLViewerMedia::getPriorityList();
+	LLViewerMedia::impl_list::iterator priority_iter;
+	
+	U32 enabled_count = 0;
+	U32 disabled_count = 0;
+	
+	// iterate over the impl list, creating rows as necessary.
+	for(priority_iter = impls.begin(); priority_iter != impls.end(); priority_iter++)
+	{
+		LLViewerMediaImpl *impl = *priority_iter;
+		
+		// If we just emptied out the list, every flag needs to be reset.
+		if(all_items_deleted)
+		{
+			impl->setInNearbyMediaList(false);
+		}
+		
+		{
+			bool remove_item = false;
+			LLUUID media_id = impl->getMediaTextureID();
+			if (impl->isParcelMedia())
+			{
+				remove_item = LLViewerParcelMedia::getURL().empty();
+			}
+			else {
+				S32 proximity = impl->getProximity();
+			// This is expensive (i.e. a linear search) -- don't use it here.  We now use mInNearbyMediaList instead.
+//			S32 index = mMediaList->getItemIndex(media_id);
+				remove_item = (proximity < 0 || !shouldShow(impl));
+			}
+			if (remove_item)
+			{
+				// This isn't inworld media -- don't show it in the list.
+				if (impl->getInNearbyMediaList())
+				{
+					// There's a row for this impl -- remove it.
+					removeMediaItem(media_id);
+					impl->setInNearbyMediaList(false);
+				}
+			}
+			else
+			{
+				if (!impl->getInNearbyMediaList())
+				{
+					// We don't have a row for this impl -- add one.
+					addMediaItem(media_id);
+					impl->setInNearbyMediaList(true);
+				}
+			}
+			// Update counts
+			if (impl->isMediaDisabled())
+			{
+				disabled_count++;
+			}
+			else {
+				enabled_count++;
+		}
+	}
+	}
+	mDisableAllCtrl->setEnabled(LLViewerMedia::isAnyMediaShowing());
+	mEnableAllCtrl->setEnabled(disabled_count > 0);
+
+	// Iterate over the rows in the control, updating ones whose impl exists, and deleting ones whose impl has gone away.
+	std::vector<LLScrollListItem*> items = mMediaList->getAllData();
+
+	for (std::vector<LLScrollListItem*>::iterator item_it = items.begin();
+		item_it != items.end();
+		++item_it)
+	{
+		LLScrollListItem* item = (*item_it);
+		LLUUID row_id = item->getUUID();
+		
+		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(row_id);
+		if(impl)
+		{
+			updateMediaItem(item, impl);
+		}
+		else
+		{
+			// This item's impl has been deleted -- remove the row.
+			// Removing the row won't throw off our iteration, since we have a local copy of the array.
+			// We just need to make sure we don't access this item after the delete.
+			removeMediaItem(row_id);
+		}
+	}
+	
+	// Set the selection to whatever media impl the media focus/hover is on. 
+	// This is an experiment, and can be removed by ifdefing out these 4 lines.
+	LLUUID media_target = LLViewerMediaFocus::getInstance()->getControlsMediaID();
+	if(media_target.notNull())
+	{
+		mMediaList->selectByID(media_target);
+	}
+}
+
+void LLPanelNearByMedia::updateColumns()
+{
+	if (!mDebugInfoVisible)
+	{
+		if (mMediaList->getColumn(VISIBILITY_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(-1);
+		if (mMediaList->getColumn(PROXIMITY_COLUMN)) mMediaList->getColumn(PROXIMITY_COLUMN)->setWidth(-1);
+		if (mMediaList->getColumn(CLASS_COLUMN)) mMediaList->getColumn(CLASS_COLUMN)->setWidth(-1);
+		if (mMediaList->getColumn(DEBUG_COLUMN)) mMediaList->getColumn(DEBUG_COLUMN)->setWidth(-1);
+	}
+	else {
+		if (mMediaList->getColumn(VISIBILITY_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(20);
+		if (mMediaList->getColumn(PROXIMITY_COLUMN)) mMediaList->getColumn(PROXIMITY_COLUMN)->setWidth(30);
+		if (mMediaList->getColumn(CLASS_COLUMN)) mMediaList->getColumn(CLASS_COLUMN)->setWidth(20);
+		if (mMediaList->getColumn(DEBUG_COLUMN)) mMediaList->getColumn(DEBUG_COLUMN)->setWidth(200);
+	}
+}
+
+void LLPanelNearByMedia::onClickEnableAll()
+	{
+	LLViewerMedia::setAllMediaEnabled(true);
+	// Parcel Audio, too
+	onClickParcelAudioPlay();
+	}
+
+void LLPanelNearByMedia::onClickDisableAll()
+	{
+	LLViewerMedia::setAllMediaEnabled(false);
+	// Parcel Audio, too
+		onClickParcelAudioStop();
+	}
+
+void LLPanelNearByMedia::onClickEnableParcelMedia()
+{	
+		LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
+	}
+
+void LLPanelNearByMedia::onClickDisableParcelMedia()
+{	
+		// This actually unloads the impl, as opposed to "stop"ping the media
+		LLViewerParcelMedia::stop();
+	}
+
+void LLPanelNearByMedia::onCheckItem(LLUICtrl* ctrl, const LLUUID &row_id)
+{	
+	LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl);
+
+	setDisabled(row_id, ! check->getValue());
+}
+
+bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled)
+{
+	LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(row_id);
+	if(impl)
+	{
+		impl->setDisabled(disabled);
+		return true;
+	}
+	return false;
+}
+								
+//static
+void LLPanelNearByMedia::onZoomMedia(void* user_data)
+{
+	LLPanelNearByMedia* panelp = (LLPanelNearByMedia*)user_data;
+	LLUUID media_id = panelp->mMediaList->getValue().asUUID();
+	
+	LLViewerMediaFocus::getInstance()->focusZoomOnMedia(media_id);
+}
+
+void LLPanelNearByMedia::onClickMuteParcelMedia()
+{
+	if (LLViewerParcelMedia::getParcelMedia())
+	{
+		bool muted = mParcelMediaMuteCtrl->getValue();
+		LLViewerParcelMedia::getParcelMedia()->setVolume(muted ? (F32)0 : mParcelMediaVolumeSlider->getValueF32() );
+	}
+}
+
+void LLPanelNearByMedia::onParcelMediaVolumeSlider()
+{
+	if (LLViewerParcelMedia::getParcelMedia())
+	{
+		LLViewerParcelMedia::getParcelMedia()->setVolume(mParcelMediaVolumeSlider->getValueF32());
+	}
+}
+
+void LLPanelNearByMedia::onClickParcelMediaPlay()
+{
+	LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
+}
+
+void LLPanelNearByMedia::onClickParcelMediaStop()
+{	
+	if (LLViewerParcelMedia::getParcelMedia())
+	{
+		// This stops the media playing, as opposed to unloading it like
+		// LLViewerParcelMedia::stop() does
+		LLViewerParcelMedia::getParcelMedia()->stop();
+	}
+}
+
+void LLPanelNearByMedia::onClickParcelMediaPause()
+{
+	LLViewerParcelMedia::pause();
+}
+
+void LLPanelNearByMedia::onClickParcelAudioPlay()
+{
+	// User *explicitly* started the internet stream, so keep the stream
+	// playing and updated as they cross to other parcels etc.
+	mParcelAudioAutoStart = true;
+
+	if (!gAudiop)
+		return;
+
+	if (PARCEL_AUDIO_PAUSED == gAudiop->isInternetStreamPlaying())
+	{
+		// 'false' means unpause
+		gAudiop->pauseInternetStream(false);
+	}
+	else {
+		gAudiop->startInternetStream(getParcelAudioURL());
+	}
+}
+
+void LLPanelNearByMedia::onClickParcelAudioStop()
+{
+	// User *explicitly* stopped the internet stream, so don't
+	// re-start audio when i.e. they move to another parcel, until
+	// they explicitly start it again.
+	mParcelAudioAutoStart = false;
+
+	if (!gAudiop)
+		return;
+
+	gAudiop->stopInternetStream();
+}
+
+void LLPanelNearByMedia::onClickParcelAudioPause()
+{
+	if (!gAudiop)
+		return;
+
+	// 'true' means pause
+	gAudiop->pauseInternetStream(true);
+}
+
+bool LLPanelNearByMedia::shouldShow(LLViewerMediaImpl* impl)
+{	
+	const LLSD &choice_llsd = mShowCtrl->getSelectedValue();
+	MediaClass choice = (MediaClass)choice_llsd.asInteger();
+
+	switch (choice)
+	{	
+		case MEDIA_CLASS_ALL:
+			return true;
+			break;
+		case MEDIA_CLASS_WITHIN_PARCEL:
+			return impl->isInAgentParcel();
+			break;
+		case MEDIA_CLASS_OUTSIDE_PARCEL:
+			return ! impl->isInAgentParcel();
+			break;
+		case MEDIA_CLASS_ON_OTHERS:
+			return impl->isAttachedToAnotherAvatar();
+			break;
+		default:
+			break;
+	}
+	return true;
+}
+
+void LLPanelNearByMedia::onAdvancedButtonClick()
+{	
+	// bring up the prefs floater
+	LLFloaterPreference* prefsfloater = dynamic_cast<LLFloaterPreference*>(LLFloaterReg::showInstance("preferences"));
+	if (prefsfloater)
+	{
+		// grab the 'audio' panel from the preferences floater and
+		// bring it the front!
+		LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core");
+		LLPanel* audiopanel = prefsfloater->getChild<LLPanel>("audio");
+		if (tabcontainer && audiopanel)
+		{
+			tabcontainer->selectTabPanel(audiopanel);
+		}
+	}
+}
+
+void LLPanelNearByMedia::onMoreLess()
+{
+	bool is_more = getChild<LLUICtrl>("more_less_btn")->getValue();
+	mNearbyMediaPanel->setVisible(is_more);
+
+	S32 new_height = mOriginalHeight;
+	if (!is_more) new_height -= mNearbyMediaPanelHeight;
+
+	LLRect new_rect = getRect();
+	new_rect.mBottom = new_rect.mTop - new_height;
+
+	setShape(new_rect);
+}
+
+// static
+void LLPanelNearByMedia::getNameAndUrlHelper(LLViewerMediaImpl* impl, std::string& name, std::string & url, const std::string &defaultName)
+{
+	if (NULL == impl) return;
+	
+	name = impl->getName();
+	url = impl->getCurrentMediaURL();	// This is the URL the media impl actually has loaded
+	if (url.empty())
+	{
+		url = impl->getMediaEntryURL();	// This is the current URL from the media data
+	}
+	if (url.empty())
+	{
+		url = impl->getHomeURL();		// This is the home URL from the media data
+	}
+	if (name.empty())
+	{
+		name = url;
+	}
+	if (name.empty())
+	{
+		name = defaultName;
+	}
+}
+
+// static
+std::string LLPanelNearByMedia::getParcelAudioURL()
+{
+	return LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL();
+}
+
+
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b30f3c0e0b008444b5c8880f20cade1202c5284
--- /dev/null
+++ b/indra/newview/llpanelnearbymedia.h
@@ -0,0 +1,160 @@
+/** 
+ * @file llpanelnearbymedia.h
+ * @brief Management interface for muting and controlling nearby media
+ *
+ * $LicenseInfo:firstyear=2005&license=viewergpl$
+ * 
+ * Copyright (c) 2005-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_LLPANELNEARBYMEDIA_H
+#define LL_LLPANELNEARBYMEDIA_H
+
+#include "llpanel.h"
+
+class LLPanelNearbyMedia;
+class LLButton;
+class LLScrollListCtrl;
+class LLSliderCtrl;
+class LLCheckBoxCtrl;
+class LLTextBox;
+class LLComboBox;
+class LLViewerMediaImpl;
+
+class LLPanelNearByMedia : public LLPanel
+{
+public:
+	
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+	/*virtual*/ void onTopLost ();
+
+	// this is part of the nearby media *dialog* so we can track whether
+	// the user *implicitly* wants audio on or off via their *explicit*
+	// interaction with our buttons.
+	bool getParcelAudioAutoStart();
+
+	LLPanelNearByMedia();
+	virtual ~LLPanelNearByMedia();
+
+private:
+	
+	enum ColumnIndex {
+		CHECKBOX_COLUMN = 0,
+		PROXIMITY_COLUMN = 1,
+		VISIBILITY_COLUMN = 2,
+		CLASS_COLUMN = 3,
+		NAME_COLUMN = 4,
+		DEBUG_COLUMN = 5
+	};
+	
+	// Media "class" enumeration
+	enum MediaClass {
+		MEDIA_CLASS_ALL = 0,
+		MEDIA_CLASS_FOCUSED = 1,
+		MEDIA_CLASS_WITHIN_PARCEL = 2,
+		MEDIA_CLASS_OUTSIDE_PARCEL = 3,
+		MEDIA_CLASS_ON_OTHERS = 4
+	};
+		
+	// Add/remove an LLViewerMediaImpl to/from the list
+	void addMediaItem(const LLUUID &id);
+	void updateMediaItem(LLScrollListItem* item, LLViewerMediaImpl* impl);
+	void removeMediaItem(const LLUUID &id);
+	
+	// Refresh the list in the UI
+	void refreshList();
+	
+	void refreshParcelMediaUI();
+	void refreshParcelAudioUI();
+
+	// UI Callbacks 
+	void onClickEnableAll();
+	void onClickDisableAll();
+	void onClickEnableParcelMedia();
+	void onClickDisableParcelMedia();
+	void onClickMuteParcelMedia();
+	void onParcelMediaVolumeSlider();
+	void onClickParcelMediaPlay();
+	void onClickParcelMediaStop();
+	void onClickParcelMediaPause();
+	void onClickParcelAudioPlay();
+	void onClickParcelAudioStop();
+	void onClickParcelAudioPause();
+	void onCheckAutoPlay();
+	void onAdvancedButtonClick();	
+	void onMoreLess();	
+	
+	void onCheckItem(LLUICtrl* ctrl, const LLUUID &row_id);
+	
+	static void onZoomMedia(void* user_data);
+	
+private:
+	bool setDisabled(const LLUUID &id, bool disabled);
+	
+	static void getNameAndUrlHelper(LLViewerMediaImpl* impl, std::string& name, std::string & url, const std::string &defaultName);
+
+	static std::string getParcelAudioURL();
+	
+	void updateColumns();
+	
+	bool shouldShow(LLViewerMediaImpl* impl);
+	
+	LLUICtrl*			mNearbyMediaPanel;
+	LLScrollListCtrl*	mMediaList;
+	LLUICtrl*			mEnableAllCtrl;
+	LLUICtrl*			mDisableAllCtrl;
+	LLSliderCtrl*		mParcelMediaVolumeSlider;
+	LLButton*			mParcelMediaMuteCtrl;
+	LLUICtrl*			mEnableParcelMediaCtrl;
+	LLUICtrl*			mDisableParcelMediaCtrl;
+	LLTextBox*			mParcelMediaText;
+	LLTextBox*			mItemCountText;
+	LLUICtrl*			mParcelMediaCtrl;
+	LLUICtrl*			mParcelMediaPlayCtrl;
+	LLUICtrl*			mParcelMediaPauseCtrl;
+	LLUICtrl*			mParcelAudioCtrl;
+	LLUICtrl*			mParcelAudioPlayCtrl;
+	LLUICtrl*			mParcelAudioPauseCtrl;
+	LLComboBox*			mShowCtrl;
+	
+	bool				mAllMediaDisabled;
+	bool				mDebugInfoVisible;
+	bool				mParcelAudioAutoStart;
+	std::string			mEmptyNameString;
+	std::string			mDefaultParcelMediaName;
+	std::string			mPlayingString;
+	
+	S32					mOriginalHeight;
+	S32					mNearbyMediaPanelHeight;
+	LLFrameTimer		mHoverTimer;
+};
+
+
+#endif // LL_LLPANELNEARBYMEDIA_H
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index 74e37efe4e45f0a0fadfddd9fc9457d29803ba5e..247134ad63aebe8d01cae30a1e0395bc6ac09b26 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -96,7 +96,10 @@ void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility )
 	else
 	{
 		mHoverTimer.stop();
-		gFocusMgr.setTopCtrl(NULL);
+		if (gFocusMgr.getTopCtrl() == this)
+		{
+			gFocusMgr.setTopCtrl(NULL);
+		}
 	}
 }
 
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index bff32af228ccb56f0da079cfb4d464aad9a412c4..025f03dc5af3c4a3e2380a90713155ec9a55ce2f 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -41,6 +41,7 @@
 #include "llviewercontrol.h"
 #include "llfloaterbuycurrency.h"
 #include "llfloaterlagmeter.h"
+#include "llpanelnearbymedia.h"
 #include "llpanelvolumepulldown.h"
 #include "llfloaterregioninfo.h"
 #include "llfloaterscriptdebug.h"
@@ -61,6 +62,7 @@
 #include "llresmgr.h"
 #include "llworld.h"
 #include "llstatgraph.h"
+#include "llviewermedia.h"
 #include "llviewermenu.h"	// for gMenuBarView
 #include "llviewerparcelmgr.h"
 #include "llviewerthrottle.h"
@@ -130,7 +132,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	
 	// status bar can possible overlay menus?
 	setMouseOpaque(FALSE);
-	setIsChrome(TRUE);
 
 	// size of day of the weeks and year
 	sDays.reserve(7);
@@ -140,9 +141,39 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mHealthTimer = new LLFrameTimer();
 
 	LLUICtrlFactory::getInstance()->buildPanel(this,"panel_status_bar.xml");
+}
+
+LLStatusBar::~LLStatusBar()
+{
+	delete mBalanceTimer;
+	mBalanceTimer = NULL;
+
+	delete mHealthTimer;
+	mHealthTimer = NULL;
+
+	// LLView destructor cleans up children
+}
+
+//-----------------------------------------------------------------------
+// Overrides
+//-----------------------------------------------------------------------
+
+// virtual
+void LLStatusBar::draw()
+{
+	refresh();
+	LLPanel::draw();
+}
 
-	// status bar can never get a tab
-	setFocusRoot(FALSE);
+BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	show_navbar_context_menu(this,x,y);
+	return TRUE;
+}
+
+BOOL LLStatusBar::postBuild()
+{
+	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
 
 	// build date necessary data (must do after panel built)
 	setupDate();
@@ -158,7 +189,10 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mBtnVolume = getChild<LLButton>( "volume_btn" );
 	mBtnVolume->setClickedCallback( onClickVolume, this );
 	mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
-	mBtnVolume->setIsChrome(TRUE);
+
+	mMediaToggle = getChild<LLButton>("media_toggle_btn");
+	mMediaToggle->setClickedCallback( &LLStatusBar::onClickMediaToggle, this );
+	mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));
 
 	gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2));
 
@@ -207,6 +241,9 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mPanelVolumePulldown = new LLPanelVolumePulldown();
 	addChild(mPanelVolumePulldown);
 
+	mPanelNearByMedia = new LLPanelNearByMedia();
+	addChild(mPanelNearByMedia);
+
 	LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect();
 	LLButton* volbtn =  getChild<LLButton>( "volume_btn" );
 	volume_pulldown_rect.setLeftTopAndSize(volbtn->getRect().mLeft -
@@ -218,39 +255,21 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mPanelVolumePulldown->setShape(volume_pulldown_rect);
 	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
 	mPanelVolumePulldown->setVisible(FALSE);
-}
-
-LLStatusBar::~LLStatusBar()
-{
-	delete mBalanceTimer;
-	mBalanceTimer = NULL;
-
-	delete mHealthTimer;
-	mHealthTimer = NULL;
-
-	// LLView destructor cleans up children
-}
-
-//-----------------------------------------------------------------------
-// Overrides
-//-----------------------------------------------------------------------
-
-// virtual
-void LLStatusBar::draw()
-{
-	refresh();
-	LLPanel::draw();
-}
 
-BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	show_navbar_context_menu(this,x,y);
-	return TRUE;
-}
-
-BOOL LLStatusBar::postBuild()
-{
-	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
+	LLRect nearby_media_rect = mPanelNearByMedia->getRect();
+	LLButton* nearby_media_btn =  getChild<LLButton>( "media_toggle_btn" );
+	nearby_media_rect.setLeftTopAndSize(nearby_media_btn->getRect().mLeft -
+	     (volume_pulldown_rect.getWidth() - nearby_media_btn->getRect().getWidth())/2,
+			       nearby_media_btn->calcScreenRect().mBottom,
+			       nearby_media_rect.getWidth(),
+			       nearby_media_rect.getHeight());
+	// force onscreen
+	nearby_media_rect.translate(getRect().getWidth() - nearby_media_rect.mRight, 0);
+
+	mPanelNearByMedia->setShape(nearby_media_rect);
+	mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
+	mPanelNearByMedia->setVisible(FALSE);
+	
 
 	return TRUE;
 }
@@ -356,6 +375,8 @@ void LLStatusBar::refresh()
 	// update the master volume button state
 	bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute();
 	mBtnVolume->setToggleState(mute_audio);
+	
+	mMediaToggle->setValue(!LLViewerMedia::isAnyMediaShowing());
 }
 
 void LLStatusBar::setVisibleForMouselook(bool visible)
@@ -513,13 +534,19 @@ static void onClickScriptDebug(void*)
 	LLFloaterScriptDebug::show(LLUUID::null);
 }
 
-//static
-void LLStatusBar::onMouseEnterVolume(LLUICtrl* ctrl)
+void LLStatusBar::onMouseEnterVolume()
+{
+	// show the master volume pull-down
+	mPanelVolumePulldown->setVisible(TRUE);
+}
+
+void LLStatusBar::onMouseEnterNearbyMedia()
 {
 	// show the master volume pull-down
-	gStatusBar->mPanelVolumePulldown->setVisible(TRUE);
+	mPanelNearByMedia->setVisible(TRUE);
 }
 
+
 static void onClickVolume(void* data)
 {
 	// toggle the master mute setting
@@ -527,6 +554,14 @@ static void onClickVolume(void* data)
 	LLAppViewer::instance()->setMasterSystemAudioMute(!mute_audio);	
 }
 
+//static 
+void LLStatusBar::onClickMediaToggle(void* data)
+{
+	LLStatusBar *status_bar = (LLStatusBar*)data;
+	// "Selected" means it was showing the "play" icon (so media was playing), and now it shows "pause", so turn off media
+	LLViewerMedia::setAllMediaEnabled(! status_bar->mMediaToggle->getValue());
+}
+
 // sets the static variables necessary for the date
 void LLStatusBar::setupDate()
 {
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 21a98dd7531e0b07b9c87ad5703e04e3dd3849f1..c37c27299f2ec531895bc21261289cd439a4729c 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -48,6 +48,7 @@ class LLUUID;
 class LLFrameTimer;
 class LLStatGraph;
 class LLPanelVolumePulldown;
+class LLPanelNearByMedia;
 
 class LLStatusBar
 :	public LLPanel
@@ -87,6 +88,8 @@ class LLStatusBar
 	S32 getSquareMetersCommitted() const;
 	S32 getSquareMetersLeft() const;
 
+	LLPanelNearByMedia* getNearbyMediaPanel() { return mPanelNearByMedia; }
+
 private:
 	// simple method to setup the part that holds the date
 	void setupDate();
@@ -94,9 +97,12 @@ class LLStatusBar
 	void onClickBuyCurrency();
 	void onVolumeChanged(const LLSD& newvalue);
 
-	static void onMouseEnterVolume(LLUICtrl* ctrl);
+	void onMouseEnterVolume();
+	void onMouseEnterNearbyMedia();
 	static void onClickStatGraph(void* data);
 
+	static void onClickMediaToggle(void* data);
+
 private:
 	LLTextBox	*mTextHealth;
 	LLTextBox	*mTextTime;
@@ -105,6 +111,7 @@ class LLStatusBar
 	LLStatGraph *mSGPacketLoss;
 
 	LLButton	*mBtnVolume;
+	LLButton	*mMediaToggle;
 
 	S32				mBalance;
 	S32				mHealth;
@@ -113,6 +120,7 @@ class LLStatusBar
 	LLFrameTimer*	mBalanceTimer;
 	LLFrameTimer*	mHealthTimer;
 	LLPanelVolumePulldown* mPanelVolumePulldown;
+	LLPanelNearByMedia*	mPanelNearByMedia;
 	static std::vector<std::string> sDays;
 	static std::vector<std::string> sMonths;
 	static const U32 MAX_DATE_STRING_LENGTH;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 29114c33c52b86903b65431519f4265ea786c62e..435636ceef67a3db92d12bcc7f1ad6789fcd97b7 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -77,7 +77,6 @@
 #include "llfloatermap.h"
 #include "llfloatermemleak.h"
 #include "llfloaternamedesc.h"
-#include "llfloaternearbymedia.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloateropenobject.h"
 #include "llfloaterpay.h"
@@ -194,7 +193,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
 	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
 
-	LLFloaterReg::add("nearby_media", "floater_nearby_media.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNearbyMedia>);
 	LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
 	LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>);
 
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 0e133f8729f039d93fa72dcb3cbd092b3e085a5a..1b6236ce4a968519a77e2da9fa50ded9f81ee400 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -50,6 +50,9 @@
 #include "llcallbacklist.h"
 #include "llparcel.h"
 #include "llaudioengine.h"  // for gAudiop
+#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llviewerregion.h"
 
 #include "llevent.h"		// LLSimpleListener
 #include "llnotificationsutil.h"
@@ -63,6 +66,10 @@
 #include <boost/signals2.hpp>
 
 /*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable";
+/*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers";
+/*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel";
+/*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel";
+
 
 // Move this to its own file.
 
@@ -254,6 +261,8 @@ static LLTimer sMediaCreateTimer;
 static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;
 static F32 sGlobalVolume = 1.0f;
 static F64 sLowestLoadableImplInterest = 0.0f;
+static bool sAnyMediaShowing = false;
+static boost::signals2::connection sTeleportFinishConnection;
 
 //////////////////////////////////////////////////////////////////////////////////////////
 static void add_media_impl(LLViewerMediaImpl* media)
@@ -366,8 +375,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
 			// The current media URL is not empty.
 			// If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent,
 			// do a navigate.
-			bool auto_play = (media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING));
-			
+			bool auto_play = media_impl->isAutoPlayable();			
 			if((was_loaded || auto_play) && !update_from_self)
 			{
 				needs_navigate = url_changed;
@@ -391,7 +399,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
 		media_impl->mMediaAutoPlay = media_entry->getAutoPlay();
 		media_impl->mMediaEntryURL = media_entry->getCurrentURL();
 		
-		if(media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING))
+		if(media_impl->isAutoPlayable())
 		{
 			needs_navigate = true;
 		}
@@ -688,6 +696,7 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi
 // static
 void LLViewerMedia::updateMedia(void *dummy_arg)
 {
+	sAnyMediaShowing = false;
 	impl_list::iterator iter = sViewerMediaImplList.begin();
 	impl_list::iterator end = sViewerMediaImplList.end();
 
@@ -818,7 +827,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 			
 			impl_count_total++;
 		}
-		
+
 		// Overrides if the window is minimized or we lost focus (taking care
 		// not to accidentally "raise" the priority either)
 		if (!gViewerWindow->getActive() /* viewer window minimized? */ 
@@ -840,7 +849,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 				new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;
 			}
 		}
-		
+					
 		pimpl->setPriority(new_priority);
 		
 		if(pimpl->getUsedInUI())
@@ -854,6 +863,29 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 		}
 
 		total_cpu += pimpl->getCPUUsage();
+		
+		// Only set sAnyMedia​Showing if it isn't used in the UI. If it isn't 
+		// parcel media, do the normal "hasMedia()" check. If it is parcel media, 
+		// hasMedia() seems to always be true, so we do some other checks to see 
+		// if there actually is parcel media  showing
+		if (!pimpl->getUsedInUI())
+		{
+			if (! pimpl->isParcelMedia())
+			{
+				if (pimpl->hasMedia())
+				{
+					sAnyMediaShowing = true;
+				}
+			}
+			else {
+				// Parcel media showing?
+				if (!LLViewerParcelMedia::getURL().empty() && LLViewerParcelMedia::getParcelMedia().notNull())
+				{
+					sAnyMediaShowing = true;
+				}
+			}
+		}
+
 	}
 
 	// Re-calculate this every time.
@@ -893,11 +925,40 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+bool LLViewerMedia::isAnyMediaShowing()
+{
+	return sAnyMediaShowing;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::setAllMediaEnabled(bool val)
+{
+	// Set "tentative" autoplay first.  We need to do this here or else
+	// re-enabling won't start up the media below.
+	gSavedSettings.setBOOL("MediaTentativeAutoPlay", val);
+	
+	// Then 
+	impl_list::iterator iter = sViewerMediaImplList.begin();
+	impl_list::iterator end = sViewerMediaImplList.end();
+	
+	for(; iter != end; iter++)
+	{
+		LLViewerMediaImpl* pimpl = *iter;
+		if (!pimpl->getUsedInUI()) 
+			pimpl->setDisabled(!val);
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::initClass()
 {
-	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL);
+	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL);	
+	sTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
+		setTeleportFinishedCallback(boost::bind(&LLViewerMedia::onTeleportFinished));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -905,6 +966,15 @@ void LLViewerMedia::initClass()
 void LLViewerMedia::cleanupClass()
 {
 	gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL);
+	sTeleportFinishConnection.disconnect();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::onTeleportFinished()
+{
+	// On teleport, clear this setting (i.e. set it to true)
+	gSavedSettings.setBOOL("MediaTentativeAutoPlay", true);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2057,6 +2127,21 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
 #endif
 }
 
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::isMediaTimeBased()
+{
+	bool result = false;
+	
+	if(mMediaSource)
+	{
+		result = mMediaSource->pluginSupportsMediaTime();
+	}
+	
+	return result;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 bool LLViewerMediaImpl::isMediaPlaying()
 {
@@ -2118,7 +2203,7 @@ void LLViewerMediaImpl::setDisabled(bool disabled)
 		else
 		{
 			// We just (re)enabled this media.  Do a navigate if auto-play is in order.
-			if(mMediaAutoPlay && gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING))
+			if(isAutoPlayable())
 			{
 				navigateTo(mMediaEntryURL, "", true, true);
 			}
@@ -2145,6 +2230,12 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
 		}
 	}
 	
+	// If this media's class is not supposed to be shown, unload
+	if (!shouldShowBasedOnClass())
+	{
+		return true;
+	}
+	
 	return false;
 }
 
@@ -2630,3 +2721,112 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
 	}
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaImpl::isAutoPlayable() const
+{
+	return (mMediaAutoPlay && 
+			gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
+			gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaImpl::shouldShowBasedOnClass() const
+{
+	// If this is parcel media or in the UI, return true always
+	if (getUsedInUI() || isParcelMedia()) return true;
+	
+	bool attached_to_another_avatar = isAttachedToAnotherAvatar();
+	bool inside_parcel = isInAgentParcel();
+	
+	//	llinfos << " hasFocus = " << hasFocus() <<
+	//	" others = " << (attached_to_another_avatar && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING)) <<
+	//	" within = " << (inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING)) <<
+	//	" outside = " << (!inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING)) << llendl;
+	
+	// If it has focus, we should show it
+	if (hasFocus())
+		return true;
+	
+	// If it is attached to an avatar and the pref is off, we shouldn't show it
+	if (attached_to_another_avatar)
+		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING);
+	
+	if (inside_parcel)
+		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING);
+	else 
+		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
+{
+	bool result = false;
+	
+	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
+	std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
+	for ( ; iter != end; iter++)
+	{
+		if (isObjectAttachedToAnotherAvatar(*iter))
+		{
+			result = true;
+			break;
+		}
+	}
+	return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+//static
+bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj)
+{
+	bool result = false;
+	LLXform *xform = obj;
+	// Walk up parent chain
+	while (NULL != xform)
+	{
+		LLViewerObject *object = dynamic_cast<LLViewerObject*> (xform);
+		if (NULL != object)
+		{
+			LLVOAvatar *avatar = object->asAvatar();
+			if (NULL != avatar && avatar != gAgent.getAvatarObject())
+			{
+				result = true;
+				break;
+			}
+		}
+		xform = xform->getParent();
+	}
+	return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaImpl::isInAgentParcel() const
+{
+	bool result = false;
+	
+	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
+	std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
+	for ( ; iter != end; iter++)
+	{
+		LLVOVolume *object = *iter;
+		if (LLViewerMediaImpl::isObjectInAgentParcel(object))
+		{
+			result = true;
+			break;
+		}
+	}
+	return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
+// static
+bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj)
+{
+	return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal()));
+}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index daad70f14f347d7e7686a93f353c19a4d0a32893..9d21b4e9febf9ebcbf48a875178d8220bcd5ce2c 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -48,7 +48,7 @@ class LLViewerMediaImpl;
 class LLUUID;
 class LLViewerMediaTexture;
 class LLMediaEntry;
-class LLVOVolume ;
+class LLVOVolume;
 class LLMimeDiscoveryResponder;
 
 typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
@@ -76,7 +76,10 @@ class LLViewerMedia
 	public:
 
 		// String to get/set media autoplay in gSavedSettings
-		static const char *AUTO_PLAY_MEDIA_SETTING;
+		static const char* AUTO_PLAY_MEDIA_SETTING;
+		static const char* SHOW_MEDIA_ON_OTHERS_SETTING;
+		static const char* SHOW_MEDIA_WITHIN_PARCEL_SETTING;
+		static const char* SHOW_MEDIA_OUTSIDE_PARCEL_SETTING;
 	
 		typedef std::vector<LLViewerMediaImpl*> impl_list;
 
@@ -99,6 +102,11 @@ class LLViewerMedia
 		static bool textureHasMedia(const LLUUID& texture_id);
 		static void setVolume(F32 volume);
 
+		// Is any media currently "showing"?  Includes Parcel Media.  Does not include media in the UI.
+		static bool isAnyMediaShowing();
+		// Set all media enabled or disabled, depending on val.   Does not include media in the UI.
+		static void setAllMediaEnabled(bool val);
+	
 		static void updateMedia(void* dummy_arg = NULL);
 
 		static void initClass();
@@ -116,7 +124,9 @@ class LLViewerMedia
 		
 		// This is the comparitor used to sort the list.
 		static bool priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2);
-		
+	
+	private:
+		static void onTeleportFinished();
 };
 
 // Implementation functions not exported into header file
@@ -199,14 +209,16 @@ class LLViewerMediaImpl
 	void updateImagesMediaStreams();
 	LLUUID getMediaTextureID() const;
 	
-	void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; };
+	void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; }
 	void setVisible(bool visible);
-	bool getVisible() const { return mVisible; };
+	bool getVisible() const { return mVisible; }
+	bool isVisible() const { return mVisible; }
 
+	bool isMediaTimeBased();
 	bool isMediaPlaying();
 	bool isMediaPaused();
 	bool hasMedia() const;
-	bool isMediaFailed() const { return mMediaSourceFailed; };
+	bool isMediaFailed() const { return mMediaSourceFailed; }
 	void setMediaFailed(bool val) { mMediaSourceFailed = val; }
 	void resetPreviousMediaState();
 	
@@ -222,10 +234,10 @@ class LLViewerMediaImpl
 	// returns true if this instance could be playable based on autoplay setting, current load state, etc.
 	bool isPlayable() const;
 	
-	void setIsParcelMedia(bool is_parcel_media) { mIsParcelMedia = is_parcel_media; };
-	bool isParcelMedia() const { return mIsParcelMedia; };
+	void setIsParcelMedia(bool is_parcel_media) { mIsParcelMedia = is_parcel_media; }
+	bool isParcelMedia() const { return mIsParcelMedia; }
 
-	ECursorType getLastSetCursor() { return mLastSetCursor; };
+	ECursorType getLastSetCursor() { return mLastSetCursor; }
 	
 	// utility function to create a ready-to-use media instance from a desired media type.
 	static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height);
@@ -326,6 +338,18 @@ class LLViewerMediaImpl
 	
 	void cancelMimeTypeProbe();
 	
+	// Is this media attached to an avatar *not* self
+	bool isAttachedToAnotherAvatar() const;
+	
+	// Is this media in the agent's parcel?
+	bool isInAgentParcel() const;
+
+private:
+	bool isAutoPlayable() const;
+	bool shouldShowBasedOnClass() const;
+	static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
+	static bool isObjectInAgentParcel(LLVOVolume *obj);
+	
 private:
 	// a single media url with some data and an impl.
 	LLPluginClassMedia* mMediaSource;
@@ -368,7 +392,7 @@ class LLViewerMediaImpl
 	LLMimeDiscoveryResponder *mMimeTypeProbe;
 	bool mMediaAutoPlay;
 	std::string mMediaEntryURL;
-	bool mInNearbyMediaList;	// used by LLFloaterNearbyMedia::refreshList() for performance reasons
+	bool mInNearbyMediaList;	// used by LLPanelNearbyMedia::refreshList() for performance reasons
 	bool mClearCache;
 	LLColor4 mBackgroundColor;
 	bool mNavigateSuspended;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 07c8867e262a3cc4befaf0d01d43bef923a00488..0c0936c1031b4ff2aa36087dc69205bc1aa0abb9 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -53,7 +53,7 @@
 //#include "llfirstuse.h"
 #include "llfloaterbuyland.h"
 #include "llfloatergroups.h"
-#include "llfloaternearbymedia.h"
+#include "llpanelnearbymedia.h"
 #include "llfloatersellland.h"
 #include "llfloatertools.h"
 #include "llparcelselection.h"
@@ -1795,11 +1795,11 @@ void optionally_start_music(const std::string& music_url)
 	{
 		// only play music when you enter a new parcel if the UI control for this
 		// was not *explicitly* stopped by the user. (part of SL-4878)
-		LLFloaterNearbyMedia *nearby_media_floater = LLFloaterReg::findTypedInstance<LLFloaterNearbyMedia>("nearby_media");
-		if ((nearby_media_floater &&
-		     nearby_media_floater->getParcelAudioAutoStart()) ||
+		LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();;
+		if ((nearby_media_panel &&
+		     nearby_media_panel->getParcelAudioAutoStart()) ||
 		    // or they have expressed no opinion in the UI, but have autoplay on...
-		    (!nearby_media_floater &&
+		    (!nearby_media_panel &&
 		     gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)))
 		{
 			llinfos << "Starting parcel music " << music_url << llendl;
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.png b/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.png
new file mode 100644
index 0000000000000000000000000000000000000000..361fab59e0a382198a5e7236cc4f036f2d3230f6
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.png differ
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4fcdb30465f4229d8f59e4d4e5fe019f59895856
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+	can_resize="true"
+	can_close="false"
+  	background_opaque="true"
+  	background_visible="true"
+	layout="topleft"
+	width="270"
+	height="310"
+	name="nearby_media"
+	help_topic="nearby_media">
+  <string name="media_item_count_format">(%ld media items)</string>
+  <string name="empty_item_text">&lt;empty&gt;</string>
+  <string name="default_parcel_media_name">Parcel Media</string>
+  <string name="playing_suffix">(playing)</string>
+	<panel
+		bevel_style="in"
+		bg_alpha_color="0 0 0 0"
+		bg_opaque_color="0 0 0 0.3"
+		follows="left|right|top"
+		top="0"
+		height="45"
+		left="0">
+	  <button
+		  name="all_nearby_media_disable_btn"
+		  follows="left"
+		  tool_tip="Turn all nearby media off"
+		left="15"
+		width="60"
+		  height="22"
+		label="Stop All">
+		<button.commit_callback
+			function="MediaListCtrl.DisableAll" />
+	  </button>
+	  <button
+		name="all_nearby_media_enable_btn"
+		  follows="left"
+		tool_tip="Turn all nearby media on"
+		  left_pad="4"
+		width="60"
+		  height="22"
+		label="Start All">
+		<button.commit_callback
+		  function="MediaListCtrl.EnableAll" />
+	  </button>
+	  <button
+		name="open_prefs_btn"
+		image_overlay="Icon_Gear_Foreground"
+		  image_disabled="PushButton_Disabled"
+		  image_disabled_selected="PushButton_Disabled"
+		  image_selected="PushButton_Selected"
+		  image_unselected="PushButton_Off"
+		  hover_glow_amount="0.15"
+		tool_tip = "Bring up media prefs"
+		top_delta="0"
+		left_pad="4"
+		  height="22"
+		min_width="28"
+		width="28">
+		<button.commit_callback
+		  function="MediaListCtrl.GoMediaPrefs" />
+	  </button>
+	  <button
+		name="more_less_btn"
+		follows="right"
+		tool_tip="Turn all nearby media on"
+		top_delta="0"
+		right="-10"
+		width="60"
+		  height="22"
+		toggle="true"
+		label="More &gt;&gt;"
+		label_selected="Less &lt;&lt;">
+		<button.commit_callback
+		  function="MediaListCtrl.MoreLess" />
+	  </button>
+	</panel>
+	<panel
+	  name="nearby_media_panel"
+		bevel_style="in"
+		border_style="line"
+		bg_alpha_color="0 0 0 0"
+		bg_opaque_color="0 0 0 0.3"
+		follows="left|right|top|bottom"
+	  top_delta="30"
+		right="-1"
+		left="0"
+	  height="230">
+	  <text
+		  type="string"
+		  length="1"
+		follows="top|left"
+		font="SansSerif"
+		left="10"
+		width="100">
+		Nearby Media
+	  </text>
+<!-- nix for now
+	  <text
+		bottom_delta="1"
+		  type="string"
+		  follows="top|left|right"
+		  font="SansSerif"
+		font.style="ITALIC"
+		  font.size="Small"
+		name="media_item_count"
+		left="115"
+		right="-10">
+	  (?? media items)
+	  </text>
+-->
+	  <text
+		  type="string"
+		  length="1"
+		follows="top|left"
+		  font="SansSerif"
+		  top_pad="15"
+		left="10"
+		width="40">
+		Show:
+	  </text>
+	  <combo_box
+		  height="23"
+		  left="50"
+		width="140"
+		  top_delta="-5"
+		follows="left|top"
+		  name="show_combo">
+		<combo_box.item
+			label="All"
+			value="0"
+			name="All" />
+		<combo_box.item
+			label="In this Parcel"
+			value="2"
+			name="WithinParcel" />
+		<combo_box.item
+			label="Outside this Parcel"
+			value="3"
+			name="OutsideParcel" />
+		<combo_box.item
+			label="On other Avatars"
+			value="4"
+			ame="OnOthers" />
+	  </combo_box>
+	  <scroll_list
+		  follows="left|top|bottom|right"
+		  column_padding="0"
+		height="100"
+		  draw_heading="false"
+		  draw_stripes="true"
+		  bg_stripe_color="0.25 0.25 0.25 0.25"
+		  top_pad="8"
+		  left="10"
+		  right="-10"
+		  name="media_list">
+		<scroll_list.columns
+			type="checkbox"
+			width="20"
+			label=""
+			name="media_checkbox_ctrl" />
+		<scroll_list.columns
+			sort_column="media_proximity"
+			width="-1"
+			label="Proximity"
+			name="media_proximity" />
+		<scroll_list.columns
+			sort_column="media_visibility"
+			width="-1"
+			label="Visible"
+			name="media_visibility" />
+		<scroll_list.columns
+			sort_column="media_class"
+			width="-1"
+			label="Class"
+			name="media_class" />
+		<scroll_list.columns
+			label="Name"
+			name="media_name" />
+		<scroll_list.columns
+			sort_column="media_debug"
+			width="-1"
+			label="Debug"
+			name="media_debug" />
+	  </scroll_list>
+	<panel
+		bevel_style="in"
+		background_visible="true" 
+		bg_alpha_color="0.0 0.0 0.0 1.0"
+		bg_opaque_color="0 0 0 0.3"
+		follows="left|right|bottom"
+	  top_pad="5"
+		height="110"
+		left="10"
+		right="-10">
+	  <check_box
+		  name="media_enabled_btn"
+		  control_name="AudioStreamingMedia"
+		  value="true"
+		  follows="left|bottom|right"
+		  height="15"
+		  tool_tip="Check this to enable all media"
+		  label="All Media Enabled"
+		  top="10"
+		left="10"/>
+	  <check_box
+		  name="media_auto_play_btn"
+		  control_name="ParcelMediaAutoPlayEnable"
+		  enabled_control="AudioStreamingMedia"
+		  value="true"
+		  follows="left|bottom|right"
+		  height="15"
+		  tool_tip="Check this to let media auto-play if it wants"
+		  label="Allow Media to auto-play"
+		  top_pad="5"
+		left="10"/>
+	  <check_box
+		  name="media_show_within_parcel_btn"
+		  control_name="MediaShowWithinParcel"
+		  enabled_control="AudioStreamingMedia"
+		  value="true"
+		  follows="left|bottom|right"
+		  height="15"
+		  tool_tip="Uncheck this to hide media within the parcel you are standing in"
+		  label="Show media within current parcel"
+		left="10"/>
+	  <check_box
+		  name="media_show_outside_parcel_btn"
+		  control_name="MediaShowOutsideParcel"
+		  enabled_control="AudioStreamingMedia"
+		  value="true"
+		  follows="left|bottom|right"
+		  height="15"
+		  tool_tip="Uncheck this to hide media outside the parcel you are standing in"
+		  label="Show media outside current parcel"
+		left="10"/>
+	  <check_box
+		  name="media_show_on_others_btn"
+		  control_name="MediaShowOnOthers"
+		  enabled_control="AudioStreamingMedia"
+		  value="true"
+		  follows="left|bottom|right"
+		  height="15"
+		  tool_tip="Uncheck this to hide media attached to other avatars nearby"
+		  label="Show media attached to other avatars"
+		left="10"/>
+	</panel>
+  </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 5754f67045ff5225694bb50789227105b8e5f42c..96c61b69f54503412752283e0e8590d743f9bba4 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -3,6 +3,7 @@
  background_opaque="true"
  background_visible="true"
  bg_opaque_color="MouseGray"
+ chrome="true" 
  follows="top|right"
  height="19"
  layout="topleft"
@@ -10,6 +11,7 @@
  mouse_opaque="false"
  name="status"
  top="19"
+ tab_stop="false" 
  width="1000">
     <panel.string
      name="StatBarDaysOfWeek">
@@ -73,7 +75,7 @@
      pad_bottom="2"
      tool_tip="Click to buy more L$"
      top="2"
-     width="71" />
+     width="45" />
     <text
      type="string"
      font="SansSerifSmall"
@@ -86,9 +88,23 @@
      left_pad="0"
      name="TimeText"
      tool_tip="Current time (Pacific)"
-     width="89">
+     width="80">
         24:00 AM PST
     </text>
+    <button
+     follows="right|top"
+     height="15"
+     image_selected="Pause_Off"
+     image_unselected="Play_Off"
+     image_pressed="Play_Press"
+     image_pressed_selected="Pause_Press"
+     is_toggle="true"
+     left_pad="15"
+     top="2"
+     name="media_toggle_btn"
+     tool_tip="Click to toggle media"
+     width="16" >
+    </button>
     <button
      follows="right|top"
      height="15"
@@ -96,7 +112,7 @@
      image_pressed="Audio_Press"
      image_unselected="Audio_Off"
      is_toggle="true"
-     left_pad="18"
+     left_pad="5"
      top="2"
      name="volume_btn"
      tool_tip="Global Volume Control"