diff --git a/etc/message.xml b/etc/message.xml
index 7ad392d0b54650cdd94463402827b064302b69a7..da08e12aa1bb84a4615fb96994ef49c92b312962 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -671,7 +671,14 @@
 
 			<key>UploadBakedTexture</key>
 			<boolean>true</boolean>
-		</map>
+			
+			<key>ObjectMedia</key>
+            		<boolean>false</boolean>
+                  
+            		<key>ObjectMediaNavigate</key>
+            		<boolean>false</boolean>
+                  
+      </map>
 
 		<key>messageBans</key>
 		<map>
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index 4b0bf6a2d9f94b5c7dfc23acf4edad7089131a3f..d5fee2828e50c5d865428365f8e74cc06ad9aae4 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -78,9 +78,9 @@ static std::set<std::string> default_trans_args;
 void init_default_trans_args()
 {
         default_trans_args.insert("SECOND_LIFE"); // World
-        default_trans_args.insert("SECOND_LIFE_VIEWER");
+        default_trans_args.insert("APP_NAME");
         default_trans_args.insert("SECOND_LIFE_GRID");
-        default_trans_args.insert("SECOND_LIFE_SUPPORT");
+        default_trans_args.insert("SUPPORT_SITE");
 }
 
 bool translate_init(std::string comma_delim_path_list,
diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h
index a626e3f085540b25044bf8596a43dba4c830c499..78f4435ed70df19f427ef639627d95068e7cb242 100644
--- a/indra/llcommon/lllslconstants.h
+++ b/indra/llcommon/lllslconstants.h
@@ -202,5 +202,18 @@ const U32	CHANGED_OWNER = 0x80;
 const U32	CHANGED_REGION = 0x100;
 const U32	CHANGED_TELEPORT = 0x200;
 const U32	CHANGED_REGION_START = 0x400;
+const U32   CHANGED_MEDIA = 0x800;
+
+// Possible error results
+const U32 LSL_STATUS_OK                 = 0;
+const U32 LSL_STATUS_MALFORMED_PARAMS   = 1000;
+const U32 LSL_STATUS_TYPE_MISMATCH      = 1001;
+const U32 LSL_STATUS_BOUNDS_ERROR       = 1002;
+const U32 LSL_STATUS_NOT_FOUND          = 1003;
+const U32 LSL_STATUS_NOT_SUPPORTED      = 1004;
+const U32 LSL_STATUS_INTERNAL_ERROR     = 1999;
+
+// Start per-function errors below, starting at 2000:
+const U32 LSL_STATUS_WHITELIST_FAILED   = 2001;
 
 #endif
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 54f153d18248c56c9c9ce6a322493eb20870ea5b..7299ede22d7d455373fb7a520ce0297d5c17e6e9 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -99,6 +99,8 @@ void LLPluginClassMedia::reset()
 	mSetMediaHeight = -1;
 	mRequestedMediaWidth = 0;
 	mRequestedMediaHeight = 0;
+	mFullMediaWidth = 0;
+	mFullMediaHeight = 0;
 	mTextureWidth = 0;
 	mTextureHeight = 0;
 	mMediaWidth = 0;
@@ -266,8 +268,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
 
 void LLPluginClassMedia::setSize(int width, int height)
 {
-	mSetMediaWidth = width;
-	mSetMediaHeight = height;
+	if((width > 0) && (height > 0))
+	{
+		mSetMediaWidth = width;
+		mSetMediaHeight = height;
+	}
+	else
+	{
+		mSetMediaWidth = -1;
+		mSetMediaHeight = -1;
+	}
 
 	setSizeInternal();
 }
@@ -279,16 +289,26 @@ void LLPluginClassMedia::setSizeInternal(void)
 		mRequestedMediaWidth = mSetMediaWidth;
 		mRequestedMediaHeight = mSetMediaHeight;
 	}
+	else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0))
+	{
+		mRequestedMediaWidth = mNaturalMediaWidth;
+		mRequestedMediaHeight = mNaturalMediaHeight;
+	}
 	else
 	{
 		mRequestedMediaWidth = mDefaultMediaWidth;
 		mRequestedMediaHeight = mDefaultMediaHeight;
 	}
 	
+	// Save these for size/interest calculations
+	mFullMediaWidth = mRequestedMediaWidth;
+	mFullMediaHeight = mRequestedMediaHeight;
+	
 	if(mAllowDownsample)
 	{
 		switch(mPriority)
 		{
+			case PRIORITY_SLIDESHOW:
 			case PRIORITY_LOW:
 				// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
 				while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
@@ -309,6 +329,12 @@ void LLPluginClassMedia::setSizeInternal(void)
 		mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
 		mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
 	}
+	
+	if(mRequestedMediaWidth > 2048)
+		mRequestedMediaWidth = 2048;
+
+	if(mRequestedMediaHeight > 2048)
+		mRequestedMediaHeight = 2048;
 }
 
 void LLPluginClassMedia::setAutoScale(bool auto_scale)
@@ -519,6 +545,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
 		std::string priority_string;
 		switch(priority)
 		{
+			case PRIORITY_UNLOADED:	
+				priority_string = "unloaded";	
+				mSleepTime = 1.0f;
+			break;
 			case PRIORITY_STOPPED:	
 				priority_string = "stopped";	
 				mSleepTime = 1.0f;
@@ -527,6 +557,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
 				priority_string = "hidden";	
 				mSleepTime = 1.0f;
 			break;
+			case PRIORITY_SLIDESHOW:
+				priority_string = "slideshow";		
+				mSleepTime = 1.0f;
+			break;
 			case PRIORITY_LOW:		
 				priority_string = "low";		
 				mSleepTime = 1.0f / 50.0f;
@@ -550,6 +584,8 @@ void LLPluginClassMedia::setPriority(EPriority priority)
 			mPlugin->setSleepTime(mSleepTime);
 		}
 		
+		LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
+		
 		// This may affect the calculated size, so recalculate it here.
 		setSizeInternal();
 	}
@@ -557,15 +593,27 @@ void LLPluginClassMedia::setPriority(EPriority priority)
 
 void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
 {
-	if(mLowPrioritySizeLimit != size)
+	int power = nextPowerOf2(size);
+	if(mLowPrioritySizeLimit != power)
 	{
-		mLowPrioritySizeLimit = size;
+		mLowPrioritySizeLimit = power;
 
 		// This may affect the calculated size, so recalculate it here.
 		setSizeInternal();
 	}
 }
 
+F64 LLPluginClassMedia::getCPUUsage()
+{
+	F64 result = 0.0f;
+	
+	if(mPlugin)
+	{
+		result = mPlugin->getCPUUsage();
+	}
+	
+	return result;
+}
 
 void LLPluginClassMedia::cut()
 {
@@ -722,7 +770,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			mNaturalMediaWidth = width;
 			mNaturalMediaHeight = height;
 			
-			setSize(width, height);
+			setSizeInternal();
 		}
 		else if(message_name == "size_change_response")
 		{
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 665a423d0763c116238c836eccf99a02326f69d6..331ca5f6dcd58ee492fc46bafc7d68eb9ce33d64 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -66,6 +66,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
 	int getTextureWidth() const;
 	int getTextureHeight() const;
+	int getFullWidth() const { return mFullMediaWidth; };
+	int getFullHeight() const { return mFullMediaHeight; };
 	
 	// This may return NULL.  Callers need to check for and handle this case.
 	unsigned char* getBitsData();
@@ -138,9 +140,11 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	
 	typedef enum 
 	{
+		PRIORITY_UNLOADED,	// media plugin isn't even loaded.
 		PRIORITY_STOPPED,	// media is not playing, shouldn't need to update at all.
 		PRIORITY_HIDDEN,	// media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
-		PRIORITY_LOW,		// media is in the far distance, may be rendered at reduced size
+		PRIORITY_SLIDESHOW,	// media is in the far distance, updates very infrequently
+		PRIORITY_LOW,		// media is in the distance, may be rendered at reduced size
 		PRIORITY_NORMAL,	// normal (default) priority
 		PRIORITY_HIGH		// media has user focus and/or is taking up most of the screen
 	}EPriority;
@@ -148,6 +152,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void setPriority(EPriority priority);
 	void setLowPrioritySizeLimit(int size);
 	
+	F64 getCPUUsage();
+
 	// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
 	std::string getCursorName() const { return mCursorName; };
 
@@ -230,6 +236,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void initializeUrlHistory(const LLSD& url_history);
 
 protected:
+
 	LLPluginClassMediaOwner *mOwner;
 
 	// Notify this object's owner that an event has occurred.
@@ -266,7 +273,11 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	int			mSetMediaWidth;
 	int			mSetMediaHeight;
 	
-	// Actual media size being set (may be affected by auto-scale)
+	// Full calculated media size (before auto-scale and downsample calculations)
+	int			mFullMediaWidth;
+	int			mFullMediaHeight;
+
+	// Actual media size being set (after auto-scale)
 	int			mRequestedMediaWidth;
 	int			mRequestedMediaHeight;
 	
diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp
index bfabc5b7ca2fbb713e732010e2ca44ae86b2ee09..e7412a1d8f880285a0ee5fa8a82cf70805eb5a55 100644
--- a/indra/llplugin/llpluginmessage.cpp
+++ b/indra/llplugin/llpluginmessage.cpp
@@ -33,6 +33,7 @@
 
 #include "llpluginmessage.h"
 #include "llsdserialize.h"
+#include "u64.h"
 
 LLPluginMessage::LLPluginMessage()
 {
@@ -93,6 +94,14 @@ void LLPluginMessage::setValueReal(const std::string &key, F64 value)
 	mMessage["params"][key] = value;
 }
 
+void LLPluginMessage::setValuePointer(const std::string &key, void* value)
+{
+	std::stringstream temp;
+	// iostreams should output pointer values in hex with an initial 0x by default.
+	temp << value;
+	setValue(key, temp.str());
+}
+
 std::string LLPluginMessage::getClass(void) const
 {
 	return mMessage["class"];
@@ -189,6 +198,20 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const
 	return result;
 }
 
+void* LLPluginMessage::getValuePointer(const std::string &key) const
+{
+	void* result = NULL;
+
+	if(mMessage["params"].has(key))
+	{
+		std::string value = mMessage["params"][key].asString();
+		
+		result = (void*)llstrtou64(value.c_str(), NULL, 16);
+	}
+	
+	return result;
+}
+
 std::string LLPluginMessage::generate(void) const
 {
 	std::ostringstream result;
diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h
index a17ec4bb984696b70d1f2775855edfac196fc0f9..f1a0e7c62436f9e8629439da8d58d7d998bf08ca 100644
--- a/indra/llplugin/llpluginmessage.h
+++ b/indra/llplugin/llpluginmessage.h
@@ -57,6 +57,7 @@ class LLPluginMessage
 	void setValueU32(const std::string &key, U32 value);
 	void setValueBoolean(const std::string &key, bool value);
 	void setValueReal(const std::string &key, F64 value);
+	void setValuePointer(const std::string &key, void *value);
 	
 	std::string getClass(void) const;
 	std::string getName(void) const;
@@ -82,6 +83,9 @@ class LLPluginMessage
 	// get the value of a key as a float.
 	F64 getValueReal(const std::string &key) const;
 
+	// get the value of a key as a pointer.
+	void* getValuePointer(const std::string &key) const;
+
 	// Flatten the message into a string
 	std::string generate(void) const;
 
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index dc516710328395784b0d0b99dfb5e191fce2a03a..450dcb3c789d989e648650e2f4e1172f88d78dbb 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -43,6 +43,7 @@ LLPluginProcessChild::LLPluginProcessChild()
 	mInstance = NULL;
 	mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
 	mSleepTime = 1.0f / 100.0f;	// default: send idle messages at 100Hz
+	mCPUElapsed = 0.0f;
 }
 
 LLPluginProcessChild::~LLPluginProcessChild()
@@ -130,6 +131,7 @@ void LLPluginProcessChild::idle(void)
 					{
 						mHeartbeat.start();
 						mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+						mCPUElapsed = 0.0f;
 						setState(STATE_PLUGIN_LOADED);
 					}
 					else
@@ -158,10 +160,22 @@ void LLPluginProcessChild::idle(void)
 					
 					mInstance->idle();
 					
-					if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
+					if(mHeartbeat.hasExpired())
 					{
+						
 						// This just proves that we're not stuck down inside the plugin code.
-						sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
+						LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
+						
+						// Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
+						// Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
+						// If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
+						heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
+						
+						sendMessageToParent(heartbeat);
+
+						mHeartbeat.reset();
+						mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+						mCPUElapsed = 0.0f;
 					}
 				}
 				// receivePluginMessage will transition to STATE_UNLOADING
@@ -253,8 +267,11 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
 	std::string buffer = message.generate();
 
 	LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
-
+	LLTimer elapsed;
+	
 	mInstance->sendMessage(buffer);
+
+	mCPUElapsed += elapsed.getElapsedTimeF64();
 }
 
 void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
@@ -317,12 +334,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 						LLPluginMessage message("base", "shm_added");
 						message.setValue("name", name);
 						message.setValueS32("size", (S32)size);
-						// shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
-						void * address = region->getMappedAddress();
-						U32 address_lo = (U32)(U64(address) & 0xFFFFFFFF);			// Extract the lower 32 bits
-						U32 address_hi = (U32)((U64(address)>>32) & 0xFFFFFFFF);	// Extract the higher 32 bits 
-						message.setValueU32("address", address_lo);
-						message.setValueU32("address_1", address_hi);
+						message.setValuePointer("address", region->getMappedAddress());
 						sendMessageToPlugin(message);
 						
 						// and send the response to the parent
@@ -380,7 +392,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 	
 	if(passMessage && mInstance != NULL)
 	{
+		LLTimer elapsed;
+
 		mInstance->sendMessage(message);
+
+		mCPUElapsed += elapsed.getElapsedTimeF64();
 	}
 }
 
@@ -454,6 +470,7 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 	
 	if(passMessage)
 	{
+		LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
 		writeMessageRaw(message);
 	}
 }
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index f92905e8bd9b248db59451350bcadbb6c5002d2c..75860bdf0a9c4fec86834e1e776b1c4173f8b761 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -102,6 +102,7 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst
 	
 	LLTimer mHeartbeat;
 	F64		mSleepTime;
+	F64		mCPUElapsed;
 	
 };
 
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index f18a117dde9823e79aca6afe9e33244d986c9798..41784a713c4b0f367ed82faeab615ccf5c008b7c 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -38,7 +38,7 @@
 #include "llapr.h"
 
 // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
-static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
+static const F32 PLUGIN_LOCKED_UP_SECONDS = 15.0f;
 
 // Somewhat longer timeout for initial launch.
 static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
@@ -87,6 +87,7 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
 {	
 	mProcess.setExecutable(launcher_filename);
 	mPluginFile = plugin_filename;
+	mCPUUsage = 0.0f;
 	
 	setState(STATE_INITIALIZED);
 }
@@ -503,6 +504,11 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
 		{
 			// this resets our timer.
 			mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
+
+			mCPUUsage = message.getValueReal("cpu_usage");
+
+			LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
+			
 		}
 		else if(message_name == "shm_add_response")
 		{
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 545eb85c9abd8c720379e869a012f337c4a21cf9..0d0b047c88c22ad81b0a4a22ab32f01bf7a22700 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -96,6 +96,8 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 	bool getDisableTimeout() { return mDisableTimeout; };
 	void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
 
+	F64 getCPUUsage() { return mCPUUsage; };
+
 private:
 
 	enum EState
@@ -140,6 +142,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 	
 	LLTimer mHeartbeat;
 	F64		mSleepTime;
+	F64		mCPUUsage;
 	
 	bool mDisableTimeout;
 };
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 478dd398fff95e25a5b6f7a63a102e8e46b2b427..d13051363786911a36c461251f67f0a0360497cf 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -17,6 +17,7 @@ include_directories(
 
 set(llprimitive_SOURCE_FILES
     llmaterialtable.cpp
+    llmediaentry.cpp
     llprimitive.cpp
     llprimtexturelist.cpp
     lltextureanim.cpp
@@ -31,6 +32,7 @@ set(llprimitive_HEADER_FILES
 
     legacy_object_types.h
     llmaterialtable.h
+    llmediaentry.h
     llprimitive.h
     llprimtexturelist.h
     lltextureanim.h
@@ -49,3 +51,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
 list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
+
+#add unit tests
+INCLUDE(LLAddBuildTest)
+SET(llprimitive_TEST_SOURCE_FILES
+  llmediaentry.cpp
+  )
+LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa04bf80e7a2544817cb1dcd38c17db934f019d4
--- /dev/null
+++ b/indra/llprimitive/llmediaentry.cpp
@@ -0,0 +1,597 @@
+/** 
+ * @file llmediaentry.cpp
+ * @brief This is a single instance of media data related to the face of a prim
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-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 "llmediaentry.h"
+#include "lllslconstants.h"
+
+#include <boost/regex.hpp>
+
+// LLSD key defines
+// DO NOT REORDER OR REMOVE THESE!
+
+// Some LLSD keys.  Do not change!
+#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR   "alt_image_enable"
+#define MEDIA_CONTROLS_KEY_STR           "controls"
+#define MEDIA_CURRENT_URL_KEY_STR        "current_url"
+#define MEDIA_HOME_URL_KEY_STR           "home_url"
+#define MEDIA_AUTO_LOOP_KEY_STR          "auto_loop"
+#define MEDIA_AUTO_PLAY_KEY_STR          "auto_play"
+#define MEDIA_AUTO_SCALE_KEY_STR         "auto_scale"
+#define MEDIA_AUTO_ZOOM_KEY_STR          "auto_zoom"
+#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR  "first_click_interact"
+#define MEDIA_WIDTH_PIXELS_KEY_STR       "width_pixels"
+#define MEDIA_HEIGHT_PIXELS_KEY_STR      "height_pixels"
+
+// "security" fields
+#define MEDIA_WHITELIST_ENABLE_KEY_STR   "whitelist_enable"
+#define MEDIA_WHITELIST_KEY_STR          "whitelist"
+
+// "permissions" fields
+#define MEDIA_PERMS_INTERACT_KEY_STR     "perms_interact"
+#define MEDIA_PERMS_CONTROL_KEY_STR      "perms_control"
+
+// "general" fields
+const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY  = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
+const char* LLMediaEntry::CONTROLS_KEY          = MEDIA_CONTROLS_KEY_STR;
+const char* LLMediaEntry::CURRENT_URL_KEY       = MEDIA_CURRENT_URL_KEY_STR;
+const char* LLMediaEntry::HOME_URL_KEY          = MEDIA_HOME_URL_KEY_STR;
+const char* LLMediaEntry::AUTO_LOOP_KEY         = MEDIA_AUTO_LOOP_KEY_STR;
+const char* LLMediaEntry::AUTO_PLAY_KEY         = MEDIA_AUTO_PLAY_KEY_STR;
+const char* LLMediaEntry::AUTO_SCALE_KEY        = MEDIA_AUTO_SCALE_KEY_STR;
+const char* LLMediaEntry::AUTO_ZOOM_KEY         = MEDIA_AUTO_ZOOM_KEY_STR;
+const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
+const char* LLMediaEntry::WIDTH_PIXELS_KEY      = MEDIA_WIDTH_PIXELS_KEY_STR;
+const char* LLMediaEntry::HEIGHT_PIXELS_KEY     = MEDIA_HEIGHT_PIXELS_KEY_STR;
+
+// "security" fields
+const char* LLMediaEntry::WHITELIST_ENABLE_KEY  = MEDIA_WHITELIST_ENABLE_KEY_STR;
+const char* LLMediaEntry::WHITELIST_KEY         = MEDIA_WHITELIST_KEY_STR;
+
+// "permissions" fields
+const char* LLMediaEntry::PERMS_INTERACT_KEY    = MEDIA_PERMS_INTERACT_KEY_STR;
+const char* LLMediaEntry::PERMS_CONTROL_KEY     = MEDIA_PERMS_CONTROL_KEY_STR;
+
+#define DEFAULT_URL_PREFIX  "http://"
+
+// Constructor(s)
+LLMediaEntry::LLMediaEntry() :
+    mAltImageEnable(false),
+    mControls(STANDARD),
+    mCurrentURL(""),
+    mHomeURL(""),
+    mAutoLoop(false),
+    mAutoPlay(false),
+    mAutoScale(false),
+    mAutoZoom(false),
+    mFirstClickInteract(false),
+    mWidthPixels(0),
+    mHeightPixels(0),
+    mWhiteListEnable(false),
+    // mWhiteList
+    mPermsInteract(PERM_ALL),
+    mPermsControl(PERM_ALL),
+    mMediaIDp(NULL)
+{
+}
+
+LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
+    mMediaIDp(NULL)
+{
+    // "general" fields
+    mAltImageEnable = rhs.mAltImageEnable;
+    mControls = rhs.mControls;
+    mCurrentURL = rhs.mCurrentURL;
+    mHomeURL = rhs.mHomeURL;
+    mAutoLoop = rhs.mAutoLoop;
+    mAutoPlay = rhs.mAutoPlay;
+    mAutoScale = rhs.mAutoScale;
+    mAutoZoom = rhs.mAutoZoom;
+    mFirstClickInteract = rhs.mFirstClickInteract;
+    mWidthPixels = rhs.mWidthPixels;
+    mHeightPixels = rhs.mHeightPixels;
+
+    // "security" fields
+    mWhiteListEnable = rhs.mWhiteListEnable;
+    mWhiteList = rhs.mWhiteList;
+
+    // "permissions" fields
+    mPermsInteract = rhs.mPermsInteract;
+    mPermsControl = rhs.mPermsControl;
+}
+
+LLMediaEntry::~LLMediaEntry()
+{
+    if (NULL != mMediaIDp)
+    {
+        delete mMediaIDp;
+    }
+}
+
+LLSD LLMediaEntry::asLLSD() const
+{
+    LLSD sd;
+    asLLSD(sd);
+    return sd;
+}
+
+//
+// LLSD functions
+//
+void LLMediaEntry::asLLSD(LLSD& sd) const
+{
+    // "general" fields
+    sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
+    sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
+    sd[CURRENT_URL_KEY] = mCurrentURL;
+    sd[HOME_URL_KEY] = mHomeURL;
+    sd[AUTO_LOOP_KEY] = mAutoLoop;
+    sd[AUTO_PLAY_KEY] = mAutoPlay;
+    sd[AUTO_SCALE_KEY] = mAutoScale;
+    sd[AUTO_ZOOM_KEY] = mAutoZoom;
+    sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
+    sd[WIDTH_PIXELS_KEY] = mWidthPixels;
+    sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
+
+    // "security" fields
+    sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
+    for (U32 i=0; i<mWhiteList.size(); i++) 
+	{
+        sd[WHITELIST_KEY].append(mWhiteList[i]);
+    }
+
+    // "permissions" fields
+    sd[PERMS_INTERACT_KEY] = mPermsInteract;
+    sd[PERMS_CONTROL_KEY] = mPermsControl;
+}
+
+// static
+bool LLMediaEntry::checkLLSD(const LLSD& sd)
+{
+    if (sd.isUndefined()) return true;
+    LLMediaEntry temp;
+    return temp.fromLLSDInternal(sd, true);
+}
+
+void LLMediaEntry::fromLLSD(const LLSD& sd)
+{
+    (void)fromLLSDInternal(sd, true);
+}
+
+void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
+{
+    (void)fromLLSDInternal(sd, false);
+}
+
+// *NOTE: returns true if NO failures to set occurred, false otherwise.
+//        However, be aware that if a failure to set does occur, it does
+//        not stop setting fields from the LLSD!
+bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
+{
+    // *HACK: we sort of cheat here and assume that status is a
+    // bit field.  We "or" into status and instead of returning
+    // it, we return whether it finishes off as LSL_STATUS_OK or not.
+    U32 status = LSL_STATUS_OK;
+    
+    // "general" fields
+    if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
+    {
+        status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
+    }
+    if ( overwrite || sd.has(CONTROLS_KEY) )
+    {
+        status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
+    }
+    if ( overwrite || sd.has(CURRENT_URL_KEY) )
+    {
+        // Don't check whitelist
+        status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
+    }
+    if ( overwrite || sd.has(HOME_URL_KEY) )
+    {
+        status |= setHomeURL( sd[HOME_URL_KEY] );
+    }
+    if ( overwrite || sd.has(AUTO_LOOP_KEY) )
+    {
+        status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
+    }
+    if ( overwrite || sd.has(AUTO_PLAY_KEY) )
+    {
+        status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
+    }
+    if ( overwrite || sd.has(AUTO_SCALE_KEY) )
+    {
+        status |= setAutoScale( sd[AUTO_SCALE_KEY] );
+    }
+    if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
+    {
+        status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
+    }
+    if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
+    {
+        status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
+    }
+    if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
+    {
+        status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
+    }
+    if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
+    {
+        status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
+    }
+
+    // "security" fields
+    if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
+    {
+        status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
+    }
+    if ( overwrite || sd.has(WHITELIST_KEY) )
+    {
+        status |= setWhiteList( sd[WHITELIST_KEY] );
+    }
+
+    // "permissions" fields
+    if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
+    {
+        status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
+    }
+    if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
+    {
+        status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
+    }
+    
+    return LSL_STATUS_OK == status;
+}
+
+LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
+{
+    if (this != &rhs)
+    {
+        // "general" fields
+        mAltImageEnable = rhs.mAltImageEnable;
+        mControls = rhs.mControls;
+        mCurrentURL = rhs.mCurrentURL;
+        mHomeURL = rhs.mHomeURL;
+        mAutoLoop = rhs.mAutoLoop;
+        mAutoPlay = rhs.mAutoPlay;
+        mAutoScale = rhs.mAutoScale;
+        mAutoZoom = rhs.mAutoZoom;
+        mFirstClickInteract = rhs.mFirstClickInteract;
+        mWidthPixels = rhs.mWidthPixels;
+        mHeightPixels = rhs.mHeightPixels;
+
+        // "security" fields
+        mWhiteListEnable = rhs.mWhiteListEnable;
+        mWhiteList = rhs.mWhiteList;
+
+        // "permissions" fields
+        mPermsInteract = rhs.mPermsInteract;
+        mPermsControl = rhs.mPermsControl;
+    }
+
+    return *this;
+}
+
+bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
+{
+    return (
+        // "general" fields
+        mAltImageEnable == rhs.mAltImageEnable &&
+        mControls == rhs.mControls &&
+        mCurrentURL == rhs.mCurrentURL &&
+        mHomeURL == rhs.mHomeURL &&
+        mAutoLoop == rhs.mAutoLoop &&
+        mAutoPlay == rhs.mAutoPlay &&
+        mAutoScale == rhs.mAutoScale &&
+        mAutoZoom == rhs.mAutoZoom &&
+        mFirstClickInteract == rhs.mFirstClickInteract &&
+        mWidthPixels == rhs.mWidthPixels &&
+        mHeightPixels == rhs.mHeightPixels &&
+
+        // "security" fields
+        mWhiteListEnable == rhs.mWhiteListEnable &&
+        mWhiteList == rhs.mWhiteList &&
+
+        // "permissions" fields
+        mPermsInteract == rhs.mPermsInteract &&
+        mPermsControl == rhs.mPermsControl
+
+        );
+}
+ 
+bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
+{
+    return (
+        // "general" fields
+        mAltImageEnable != rhs.mAltImageEnable ||
+        mControls != rhs.mControls ||
+        mCurrentURL != rhs.mCurrentURL ||
+        mHomeURL != rhs.mHomeURL ||
+        mAutoLoop != rhs.mAutoLoop ||
+        mAutoPlay != rhs.mAutoPlay ||
+        mAutoScale != rhs.mAutoScale ||
+        mAutoZoom != rhs.mAutoZoom ||
+        mFirstClickInteract != rhs.mFirstClickInteract ||
+        mWidthPixels != rhs.mWidthPixels ||
+        mHeightPixels != rhs.mHeightPixels ||
+
+        // "security" fields
+        mWhiteListEnable != rhs.mWhiteListEnable ||
+        mWhiteList != rhs.mWhiteList ||
+
+        // "permissions" fields
+        mPermsInteract != rhs.mPermsInteract ||
+        mPermsControl != rhs.mPermsControl 
+        
+        );
+}
+
+U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
+{
+    // *NOTE: This code is VERY similar to the setWhitelist below.
+    // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
+    U32 size = 0;
+    U32 count = 0;
+    // First count to make sure the size constraint is not violated
+    std::vector<std::string>::const_iterator iter = whitelist.begin();
+    std::vector<std::string>::const_iterator end = whitelist.end();
+    for ( ; iter < end; ++iter) 
+    {
+        const std::string &entry = (*iter);
+        size += entry.length() + 1; // Include one for \0
+        count ++;
+        if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) 
+		{
+            return LSL_STATUS_BOUNDS_ERROR;
+        }
+    }
+    // Next clear the vector
+    mWhiteList.clear();
+    // Then re-iterate and copy entries
+    iter = whitelist.begin();
+    for ( ; iter < end; ++iter)
+    {
+        const std::string &entry = (*iter);
+        mWhiteList.push_back(entry);
+    }
+    return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
+{
+    // If whitelist is undef, this is a no-op.
+    if (whitelist.isUndefined()) return LSL_STATUS_OK;
+
+    // However, if the whitelist is an empty array, erase it.
+    if (whitelist.isArray()) 
+    {
+        // *NOTE: This code is VERY similar to the setWhitelist above.
+        // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
+        U32 size = 0;
+        U32 count = 0;
+        // First check to make sure the size and count constraints are not violated
+        LLSD::array_const_iterator iter = whitelist.beginArray();
+        LLSD::array_const_iterator end = whitelist.endArray();
+        for ( ; iter < end; ++iter) 
+        {
+            const std::string &entry = (*iter).asString();
+            size += entry.length() + 1; // Include one for \0
+            count ++;
+            if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) 
+			{
+                return LSL_STATUS_BOUNDS_ERROR;
+            }
+        }
+        // Next clear the vector
+        mWhiteList.clear();
+        // Then re-iterate and copy entries
+        iter = whitelist.beginArray();
+        for ( ; iter < end; ++iter)
+        {
+            const std::string &entry = (*iter).asString();
+            mWhiteList.push_back(entry);
+        }
+        return LSL_STATUS_OK;
+    }
+    else 
+	{
+        return LSL_STATUS_MALFORMED_PARAMS;
+    }
+}
+
+
+static void prefix_with(std::string &str, const char *chars, const char *prefix)
+{
+    // Given string 'str', prefix all instances of any character in 'chars'
+    // with 'prefix'
+    size_t found = str.find_first_of(chars);
+    size_t prefix_len = strlen(prefix);
+    while (found != std::string::npos)
+    {
+        str.insert(found, prefix, prefix_len);
+        found = str.find_first_of(chars, found+prefix_len+1);
+    }
+}
+
+static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
+{
+    // If the pattern is empty, it matches
+    if (pattern.empty()) return true;
+    
+    // 'pattern' is a glob pattern, we only accept '*' chars
+    // copy it
+    std::string expression = pattern;
+    
+    // Escape perl's regexp chars with a backslash, except all "*" chars
+    prefix_with(expression, ".[{()\\+?|^$", "\\");
+    prefix_with(expression, "*", ".");
+                    
+    // case-insensitive matching:
+    boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
+    return boost::regex_match(candidate_str, regexp);
+}
+
+bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
+{
+    if (getWhiteListEnable()) 
+    {
+        return checkUrlAgainstWhitelist(url, getWhiteList());
+    }
+    else 
+	{
+        return true;
+    }
+}
+
+// static
+bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, 
+                                            const std::vector<std::string> &whitelist)
+{
+    bool passes = true;
+    // *NOTE: no entries?  Don't check
+    if (whitelist.size() > 0) 
+    {
+        passes = false;
+            
+        // Case insensitive: the reason why we toUpper both this and the
+        // filter
+        std::string candidate_url = url;
+        // Use lluri to see if there is a path part in the candidate URL.  No path?  Assume "/"
+        LLURI candidate_uri(candidate_url);
+        std::vector<std::string>::const_iterator iter = whitelist.begin();
+        std::vector<std::string>::const_iterator end = whitelist.end();
+        for ( ; iter < end; ++iter )
+        {
+            std::string filter = *iter;
+                
+            LLURI filter_uri(filter);
+            bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
+            if (filter_uri.scheme().empty()) 
+            {
+                filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
+            }
+            bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
+            bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
+
+            if (scheme_passes && authority_passes && path_passes)
+            {
+                passes = true;
+                break;
+            }
+        }
+    }
+    return passes;
+}
+
+U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
+{
+    if ( value.length() > limit ) 
+	{
+        return LSL_STATUS_BOUNDS_ERROR;
+    }
+    else 
+	{
+        field = value;
+        return LSL_STATUS_OK;
+    }
+}
+
+U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
+{
+    if (controls == STANDARD ||
+        controls == MINI)
+    {
+        mControls = controls;
+        return LSL_STATUS_OK;
+    }
+    return LSL_STATUS_BOUNDS_ERROR;
+}
+
+U32 LLMediaEntry::setPermsInteract( U8 val )
+{
+    mPermsInteract = val & PERM_MASK;
+    return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setPermsControl( U8 val )
+{
+    mPermsControl = val & PERM_MASK;
+    return LSL_STATUS_OK;
+}
+
+U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
+{
+    return setCurrentURLInternal( current_url, true );
+}
+
+U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
+{
+    if ( ! check_whitelist || checkCandidateUrl(current_url)) 
+    {
+        return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
+    }
+    else 
+	{
+        return LSL_STATUS_WHITELIST_FAILED;
+    }
+}
+
+U32 LLMediaEntry::setHomeURL(const std::string& home_url)
+{
+    return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
+}
+
+U32 LLMediaEntry::setWidthPixels(U16 width)
+{
+    if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
+    mWidthPixels = width;
+    return LSL_STATUS_OK; 
+}
+
+U32 LLMediaEntry::setHeightPixels(U16 height)
+{
+    if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
+    mHeightPixels = height;
+    return LSL_STATUS_OK; 
+}
+
+const LLUUID &LLMediaEntry::getMediaID() const
+{
+    // Lazily generate media ID
+    if (NULL == mMediaIDp)
+    {
+        mMediaIDp = new LLUUID();
+        mMediaIDp->generate();
+    }
+    return *mMediaIDp;
+}
+
diff --git a/indra/llprimitive/llmediaentry.h b/indra/llprimitive/llmediaentry.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a5486666a42df0f8798bf930515690d01b8a7a0
--- /dev/null
+++ b/indra/llprimitive/llmediaentry.h
@@ -0,0 +1,228 @@
+/** 
+ * @file llmediaentry.h
+ * @brief This is a single instance of media data related to the face of a prim
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-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_LLMEDIAENTRY_H
+#define LL_LLMEDIAENTRY_H
+
+#include "llsd.h"
+#include "llstring.h"
+
+// For return values of set*
+#include "lllslconstants.h"
+
+class LLMediaEntry
+{
+public: 
+    enum MediaControls {
+        STANDARD = 0,
+        MINI
+    };
+    
+    // Constructors
+    LLMediaEntry();
+    LLMediaEntry(const LLMediaEntry &rhs);
+
+    LLMediaEntry &operator=(const LLMediaEntry &rhs);
+    virtual ~LLMediaEntry();
+
+    bool operator==(const LLMediaEntry &rhs) const;
+    bool operator!=(const LLMediaEntry &rhs) const;
+    
+    // Render as LLSD
+    LLSD asLLSD() const;
+    void asLLSD(LLSD& sd) const;
+    operator LLSD() const { return asLLSD(); }
+    // Returns false iff the given LLSD contains fields that violate any bounds
+    // limits.
+    static bool checkLLSD(const LLSD& sd);
+    // This doesn't merge, it overwrites the data, so will use
+    // LLSD defaults if need be.  Note: does not check limits!
+    // Use checkLLSD() above first to ensure the LLSD is valid.
+    void fromLLSD(const LLSD& sd);  
+    // This merges data from the incoming LLSD into our fields.
+    // Note that it also does NOT check limits!  Use checkLLSD() above first.
+    void mergeFromLLSD(const LLSD& sd);
+
+    // "general" fields
+    bool getAltImageEnable() const { return mAltImageEnable; }
+    MediaControls getControls() const { return mControls; }
+    std::string getCurrentURL() const { return mCurrentURL; }
+    std::string getHomeURL() const { return mHomeURL; }
+    bool getAutoLoop() const { return mAutoLoop; }
+    bool getAutoPlay() const { return mAutoPlay; }
+    bool getAutoScale() const { return mAutoScale; }
+    bool getAutoZoom() const { return mAutoZoom; }
+    bool getFirstClickInteract() const { return mFirstClickInteract; }
+    U16 getWidthPixels() const { return mWidthPixels; }
+    U16 getHeightPixels() const { return mHeightPixels; }
+
+    // "security" fields
+    bool getWhiteListEnable() const { return mWhiteListEnable; }
+    const std::vector<std::string> &getWhiteList() const { return mWhiteList; }
+
+    // "permissions" fields
+    U8 getPermsInteract() const { return mPermsInteract; }
+    U8 getPermsControl() const { return mPermsControl; }
+
+    // Setters.  Those that return a U32 return a status error code
+    // See lllslconstants.h
+    
+    // "general" fields
+    U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; }
+    U32 setControls(MediaControls controls);
+    U32 setCurrentURL(const std::string& current_url);
+    U32 setHomeURL(const std::string& home_url);
+    U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; }
+    U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; }
+    U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; }
+    U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; }
+    U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; }
+    U32 setWidthPixels(U16 width);
+    U32 setHeightPixels(U16 height);
+
+    // "security" fields
+    U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; }
+    U32 setWhiteList( const std::vector<std::string> &whitelist );
+    U32 setWhiteList( const LLSD &whitelist );  // takes an LLSD array
+
+    // "permissions" fields
+    U32 setPermsInteract( U8 val );
+    U32 setPermsControl( U8 val );
+
+    const LLUUID& getMediaID() const;
+
+    // Helper function to check a candidate URL against the whitelist
+    // Returns true iff candidate URL passes (or if there is no whitelist), false otherwise
+    bool checkCandidateUrl(const std::string& url) const;
+
+public:
+    // Static function to check a URL against a whitelist
+    // Returns true iff url passes the given whitelist
+    static bool checkUrlAgainstWhitelist(const std::string &url, 
+                                         const std::vector<std::string> &whitelist);
+    
+public:
+        // LLSD key defines
+    // "general" fields
+    static const char*  ALT_IMAGE_ENABLE_KEY;
+    static const char*  CONTROLS_KEY;
+    static const char*  CURRENT_URL_KEY;
+    static const char*  HOME_URL_KEY;
+    static const char*  AUTO_LOOP_KEY;
+    static const char*  AUTO_PLAY_KEY;
+    static const char*  AUTO_SCALE_KEY;
+    static const char*  AUTO_ZOOM_KEY;
+    static const char*  FIRST_CLICK_INTERACT_KEY;
+    static const char*  WIDTH_PIXELS_KEY;
+    static const char*  HEIGHT_PIXELS_KEY;
+
+    // "security" fields
+    static const char*  WHITELIST_ENABLE_KEY;
+    static const char*  WHITELIST_KEY;
+
+    // "permissions" fields
+    static const char*  PERMS_INTERACT_KEY;
+    static const char*  PERMS_CONTROL_KEY;
+
+    // Field enumerations & constants
+
+    // *NOTE: DO NOT change the order of these, and do not insert values
+    // in the middle!
+    // Add values to the end, and make sure to change PARAM_MAX_ID!
+    enum Fields {
+         ALT_IMAGE_ENABLE_ID = 0,
+         CONTROLS_ID = 1,
+         CURRENT_URL_ID = 2,
+         HOME_URL_ID = 3,
+         AUTO_LOOP_ID = 4,
+         AUTO_PLAY_ID = 5,
+         AUTO_SCALE_ID = 6,
+         AUTO_ZOOM_ID = 7,
+         FIRST_CLICK_INTERACT_ID = 8,
+         WIDTH_PIXELS_ID = 9,
+         HEIGHT_PIXELS_ID = 10,
+         WHITELIST_ENABLE_ID = 11,
+         WHITELIST_ID = 12,
+         PERMS_INTERACT_ID = 13,
+         PERMS_CONTROL_ID = 14,
+         PARAM_MAX_ID = PERMS_CONTROL_ID
+    };
+
+    // "permissions" values
+    // (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP
+    static const U8    PERM_NONE             = 0x0;
+    static const U8    PERM_OWNER            = 0x1;
+    static const U8    PERM_GROUP            = 0x2;
+    static const U8    PERM_ANYONE           = 0x4;
+    static const U8    PERM_ALL              = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
+    static const U8    PERM_MASK             = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
+
+    // Limits (in bytes)
+    static const U32   MAX_URL_LENGTH        = 1024;
+    static const U32   MAX_WHITELIST_SIZE    = 1024;
+    static const U32   MAX_WHITELIST_COUNT   = 64;
+    static const U16   MAX_WIDTH_PIXELS      = 2048;
+    static const U16   MAX_HEIGHT_PIXELS     = 2048;
+
+private:
+
+    U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit );
+    U32 setCurrentURLInternal( const std::string &url, bool check_whitelist);
+    bool fromLLSDInternal(const LLSD &sd, bool overwrite);
+
+private:
+     // "general" fields
+    bool mAltImageEnable;
+    MediaControls mControls;
+    std::string mCurrentURL;
+    std::string mHomeURL;
+    bool mAutoLoop;
+    bool mAutoPlay;
+    bool mAutoScale;
+    bool mAutoZoom;
+    bool mFirstClickInteract;
+    U16 mWidthPixels;
+    U16 mHeightPixels;
+
+    // "security" fields
+    bool mWhiteListEnable;
+    std::vector<std::string> mWhiteList;
+
+    // "permissions" fields
+    U8 mPermsInteract;
+    U8 mPermsControl;
+    
+    mutable LLUUID *mMediaIDp;            // temporary id assigned to media on the viewer
+};
+
+#endif
+
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 4e733ff56a2ac28271d4569202d295853b944cf0..d307d4bbfb340701c940895158f0c3d602f75678 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1319,6 +1319,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
 		color.mV[VALPHA]	= F32(255 - coloru.mV[VALPHA]) / 255.f;
 
 		retval |= setTEColor(i, color);
+
 	}
 
 	return retval;
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 3bcd831142a2ab1a8db7a07f7554d5aa7d45ffe6..b534939dfc436d741731d62f4784df083ce0dc93 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -32,13 +32,31 @@
 
 #include "linden_common.h"
 
+#include "lluuid.h"
+#include "llmediaentry.h"
 #include "lltextureentry.h"
 #include "llsdutil.h"
+#include "v4color.h"
 
 const U8 DEFAULT_BUMP_CODE = 0;  // no bump or shininess
 
 const LLTextureEntry LLTextureEntry::null;
 
+// Some LLSD keys.  Do not change these!
+#define OBJECT_ID_KEY_STR "object_id"
+#define TEXTURE_INDEX_KEY_STR "texture_index"
+#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
+#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
+#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
+
+/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
+/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
+/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
+
+static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
+
 // static 
 LLTextureEntry* LLTextureEntry::newTextureEntry()
 {
@@ -47,16 +65,19 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
 
 //===============================================================
 LLTextureEntry::LLTextureEntry()
+  : mMediaEntry(NULL)
 {
 	init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
 }
 
 LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
+  : mMediaEntry(NULL)
 {
 	init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
 }
 
 LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
+  : mMediaEntry(NULL)
 {
 	mID = rhs.mID;
 	mScaleS = rhs.mScaleS;
@@ -68,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
 	mBump = rhs.mBump;
 	mMediaFlags = rhs.mMediaFlags;
 	mGlow = rhs.mGlow;
+	if (rhs.mMediaEntry != NULL) {
+		// Make a copy
+		mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+	}
 }
 
 LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -84,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
 		mBump = rhs.mBump;
 		mMediaFlags = rhs.mMediaFlags;
 		mGlow = rhs.mGlow;
+		if (mMediaEntry != NULL) {
+			delete mMediaEntry;
+		}
+		if (rhs.mMediaEntry != NULL) {
+			// Make a copy
+			mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+		}
+		else {
+			mMediaEntry = NULL;
+		}
 	}
 
 	return *this;
@@ -103,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
     mGlow = 0;
 	
 	setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
+	if (mMediaEntry != NULL) {
+	    delete mMediaEntry;
+	}
+	mMediaEntry = NULL;
 }
 
 LLTextureEntry::~LLTextureEntry()
 {
+	if(mMediaEntry)
+	{
+		delete mMediaEntry;
+		mMediaEntry = NULL;
+	}
 }
 
 bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -158,10 +202,17 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
 	sd["bump"] = getBumpShiny();
 	sd["fullbright"] = getFullbright();
 	sd["media_flags"] = mMediaFlags;
+	if (hasMedia()) {
+		LLSD mediaData;
+        if (NULL != getMediaData()) {
+            getMediaData()->asLLSD(mediaData);
+        }
+		sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
+	}
 	sd["glow"] = mGlow;
 }
 
-bool LLTextureEntry::fromLLSD(LLSD& sd)
+bool LLTextureEntry::fromLLSD(const LLSD& sd)
 {
 	const char *w, *x;
 	w = "imageid";
@@ -206,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
 	{
 		setMediaTexGen( sd[w].asInteger() );
 	} else goto fail;
+	// If the "has media" flag doesn't match the fact that 
+	// media data exists, updateMediaData will "fix" it
+	// by either clearing or setting the flag
+	w = TEXTURE_MEDIA_DATA_KEY;
+	if (hasMedia() != sd.has(w))
+	{
+		llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
+			") does not match presence of media_data (" << sd.has(w) << ").  Fixing." << llendl;
+	}
+	updateMediaData(sd[w]);
+
 	w = "glow";
 	if (sd.has(w))
 	{
@@ -370,7 +432,19 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
 	if (mMediaFlags != media)
 	{
 		mMediaFlags = media;
-		return TEM_CHANGE_TEXTURE;
+
+		// Special code for media handling
+		if( hasMedia() && mMediaEntry == NULL)
+		{
+			mMediaEntry = new LLMediaEntry;
+		}
+        else if ( ! hasMedia() && mMediaEntry != NULL)
+        {
+            delete mMediaEntry;
+            mMediaEntry = NULL;
+        }
+
+		return TEM_CHANGE_MEDIA;
 	}
 	return TEM_CHANGE_NONE;
 }
@@ -430,7 +504,19 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
 	{
 		mMediaFlags &= ~TEM_MEDIA_MASK;
 		mMediaFlags |= media_flags;
-		return TEM_CHANGE_TEXTURE;
+        
+		// Special code for media handling
+		if( hasMedia() && mMediaEntry == NULL)
+		{
+			mMediaEntry = new LLMediaEntry;
+		}
+        else if ( ! hasMedia() && mMediaEntry != NULL)
+        {
+            delete mMediaEntry;
+            mMediaEntry = NULL;
+        }
+        
+		return TEM_CHANGE_MEDIA;
 	}
 	return TEM_CHANGE_NONE;
 }
@@ -456,3 +542,107 @@ S32 LLTextureEntry::setGlow(F32 glow)
 	}
 	return TEM_CHANGE_NONE;
 }
+
+void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
+{
+    mMediaFlags |= MF_HAS_MEDIA;
+    if (NULL != mMediaEntry)
+    {
+        delete mMediaEntry;
+    }
+    mMediaEntry = new LLMediaEntry(media_entry);
+}
+
+bool LLTextureEntry::updateMediaData(const LLSD& media_data)
+{
+	if (media_data.isUndefined())
+	{
+		// clear the media data
+        clearMediaData();
+		return false;
+	}
+	else {
+		mMediaFlags |= MF_HAS_MEDIA;
+		if (mMediaEntry == NULL)
+		{
+			mMediaEntry = new LLMediaEntry;
+		}
+        // *NOTE: this will *clobber* all of the fields in mMediaEntry 
+        // with whatever fields are present (or not present) in media_data!
+ 		mMediaEntry->fromLLSD(media_data);
+		return true;
+	}
+}
+
+void LLTextureEntry::clearMediaData()
+{
+    mMediaFlags &= ~MF_HAS_MEDIA;
+    if (mMediaEntry != NULL) {
+        delete mMediaEntry;
+    }
+    mMediaEntry = NULL;
+}    
+
+void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
+{
+    mMediaFlags |= MF_HAS_MEDIA;
+    if (mMediaEntry == NULL)
+    {
+        mMediaEntry = new LLMediaEntry;
+    }
+    // *NOTE: this will *merge* the data in media_fields
+    // with the data in our media entry
+    mMediaEntry->mergeFromLLSD(media_fields);
+}
+
+//static
+std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
+{
+    // XXX TODO: make media version string binary (base64-encoded?)
+    // Media "URL" is a representation of a version and the last-touched agent
+    // x-mv:nnnnn/agent-id
+    // where "nnnnn" is version number
+    // *NOTE: not the most efficient code in the world...
+    U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
+    const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
+    char buf[MAX_VERSION_LEN+1];
+    snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version);  // added int cast to fix warning/breakage on mac.
+    return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
+}
+
+//static
+U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
+{
+    U32 version = 0;
+    if (!version_string.empty()) 
+    {
+        size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+        if (found != std::string::npos) 
+        {
+            found = version_string.find_first_of("/", found);
+            std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
+            version = strtoul(v.c_str(),NULL,10);
+        }
+    }
+    return version;
+}
+
+//static
+LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
+{
+    LLUUID id;
+    if (!version_string.empty()) 
+    {
+        size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+        if (found != std::string::npos) 
+        {
+            found = version_string.find_first_of("/", found);
+            if (found != std::string::npos) 
+            {
+                std::string v = version_string.substr(found + 1);
+                id.set(v);
+            }
+        }
+    }
+    return id;
+}
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 84870e93e6c62c14714daafde3f7311172e6a1a0..8d2834f78c5a4218718dd55154059da8531e73a8 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -37,10 +37,13 @@
 #include "v4color.h"
 #include "llsd.h"
 
+// These bits are used while unpacking TEM messages to tell which aspects of
+// the texture entry changed.
 const S32 TEM_CHANGE_NONE = 0x0;
 const S32 TEM_CHANGE_COLOR = 0x1;
 const S32 TEM_CHANGE_TEXTURE = 0x2;
-const S32 TEM_INVALID = 0x4;
+const S32 TEM_CHANGE_MEDIA = 0x4;
+const S32 TEM_INVALID = 0x8;
 
 const S32 TEM_BUMPMAP_COUNT = 32;
 
@@ -65,6 +68,8 @@ const S32 TEM_MEDIA_MASK		= 0x01;
 const S32 TEM_TEX_GEN_MASK		= 0x06;
 const S32 TEM_TEX_GEN_SHIFT		= 1;
 
+// forward declarations
+class LLMediaEntry;
 
 class LLTextureEntry
 {
@@ -92,7 +97,7 @@ class LLTextureEntry
 	LLSD asLLSD() const;
 	void asLLSD(LLSD& sd) const;
 	operator LLSD() const { return asLLSD(); }
-	bool fromLLSD(LLSD& sd);
+	bool fromLLSD(const LLSD& sd);
 
 	virtual LLTextureEntry* newBlank() const;
 	virtual LLTextureEntry* newCopy() const;
@@ -140,9 +145,35 @@ class LLTextureEntry
 	U8	 getTexGen() const	{ return mMediaFlags & TEM_TEX_GEN_MASK; }
 	U8	 getMediaTexGen() const { return mMediaFlags; }
     F32  getGlow() const { return mGlow; }
-	
+
+    // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
+    // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
+    // to NOT return NULL.  
+	bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); } 
+	LLMediaEntry* getMediaData() const { return mMediaEntry; }
+
+    // Completely change the media data on this texture entry.
+    void setMediaData(const LLMediaEntry &media_entry);
+	// Returns true if media data was updated, false if it was cleared
+	bool updateMediaData(const LLSD& media_data);
+    // Clears media data, and sets the media flags bit to 0
+    void clearMediaData();
+    // Merges the given LLSD of media fields with this media entry.
+    // Only those fields that are set that match the keys in
+    // LLMediaEntry will be affected.  If no fields are set or if
+    // the LLSD is undefined, this is a no-op.
+    void mergeIntoMediaData(const LLSD& media_fields);
+
+    // Takes a media version string (an empty string or a previously-returned string)
+    // and returns a "touched" string, touched by agent_id
+    static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id);
+    // Given a media version string, return the version
+    static U32 getVersionFromMediaVersionString(const std::string &version_string);
+    // Given a media version string, return the UUID of the agent
+    static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string);
+
 	// Media flags
-	enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 };
+	enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
 
 public:
 	F32                 mScaleS;                // S, T offset
@@ -152,6 +183,14 @@ class LLTextureEntry
 	F32                 mRotation;              // anti-clockwise rotation in rad about the bottom left corner
 
 	static const LLTextureEntry null;
+
+	// LLSD key defines
+	static const char* OBJECT_ID_KEY;
+	static const char* OBJECT_MEDIA_DATA_KEY;
+    static const char* MEDIA_VERSION_KEY;
+	static const char* TEXTURE_INDEX_KEY;
+	static const char* TEXTURE_MEDIA_DATA_KEY;
+
 protected:
 	LLUUID				mID;					// Texture GUID
 	LLColor4			mColor;
@@ -159,6 +198,9 @@ class LLTextureEntry
 	U8					mMediaFlags;			// replace with web page, movie, etc.
 	F32                 mGlow;
 
+	// Note the media data is not sent via the same message structure as the rest of the TE
+	LLMediaEntry*		mMediaEntry;			// The media data for the face
+
 	// NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the
 	// message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs()
 
diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..72478d0459112198b7a7f2e6282d456965ce6608
--- /dev/null
+++ b/indra/llprimitive/tests/llmediaentry_test.cpp
@@ -0,0 +1,484 @@
+/** 
+ * @file llmediaentry_test.cpp
+ * @brief llmediaentry unit tests
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$                               
+ * Copyright (c) 2001-2009, Linden Research, Inc.                               
+ * $/LicenseInfo$                                                               
+ */
+
+#include "linden_common.h"
+#include "lltut.h"
+#include "boost/lexical_cast.hpp"
+#include "llstring.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#include "../llmediaentry.h"
+#include "lllslconstants.h"
+
+#define DEFAULT_MEDIA_ENTRY "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string />\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>7</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>7</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+#define EMPTY_MEDIA_ENTRY "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string />\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>0</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>0</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\
+ <map>\n\
+ <key>alt_image_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_loop</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_play</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_scale</key>\n\
+ <boolean>0</boolean>\n\
+ <key>auto_zoom</key>\n\
+ <boolean>0</boolean>\n\
+ <key>controls</key>\n\
+ <integer>0</integer>\n\
+ <key>current_url</key>\n\
+ <string>" CURRENT_URL "</string>\n\
+ <key>first_click_interact</key>\n\
+ <boolean>0</boolean>\n\
+ <key>height_pixels</key>\n\
+ <integer>0</integer>\n\
+ <key>home_url</key>\n\
+ <string />\n\
+ <key>perms_control</key>\n\
+ <integer>0</integer>\n\
+ <key>perms_interact</key>\n\
+ <integer>0</integer>\n\
+ <key>whitelist_enable</key>\n\
+ <boolean>0</boolean>\n\
+ <key>width_pixels</key>\n\
+ <integer>0</integer>\n\
+ </map>\n\
+ </llsd>"
+
+namespace tut
+{
+    // this is fixture data that gets created before each test and destroyed
+    // after each test.  this is where we put all of the setup/takedown code
+    // and data needed for each test.
+    struct MediaEntry_test
+    {
+        MediaEntry_test() {
+            emptyMediaEntryStr = EMPTY_MEDIA_ENTRY;
+            std::istringstream e(EMPTY_MEDIA_ENTRY);
+            LLSDSerialize::fromXML(emptyMediaEntryLLSD, e);
+            defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY;
+            std::istringstream d(DEFAULT_MEDIA_ENTRY);
+            LLSDSerialize::fromXML(defaultMediaEntryLLSD, d);
+        }     
+        std::string emptyMediaEntryStr;
+        LLSD emptyMediaEntryLLSD;
+        std::string defaultMediaEntryStr;
+        LLSD defaultMediaEntryLLSD;
+    };
+
+    typedef test_group<MediaEntry_test, 55> factory;
+    typedef factory::object object;
+}
+        
+
+namespace
+{
+    // this is for naming our tests to make pretty output
+    tut::factory tf("MediaEntry Test");
+}
+
+namespace tut
+{
+    bool llsd_equals(const LLSD& a, const LLSD& b) {
+        // cheesy, brute force, but it works
+        return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b));
+    }
+
+    void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
+    {
+        if (! llsd_equals(expected, actual))
+        {
+            std::string message = msg;
+            message += ": actual: ";
+            message += ll_pretty_print_sd(actual);
+            message += "\n  expected: ";
+            message += ll_pretty_print_sd(expected);
+            message += "\n";
+            ensure(message, false);
+        }
+    }
+
+    void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual)
+    {
+        if ( expected != actual )
+        {
+            std::string message = msg;
+            message += ": actual: ";
+            message += actual;
+            message += "\n  expected: ";
+            message += expected;
+            message += "\n";
+            ensure(message, false);
+        }
+    }
+
+    void set_whitelist(LLMediaEntry &entry, const char *str)
+    {
+        std::vector<std::string> tokens;
+        LLStringUtil::getTokens(std::string(str), tokens, ",");
+        entry.setWhiteList(tokens);
+    }
+
+    void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
+    {
+        std::string message = "Whitelist test";
+        LLMediaEntry entry;
+        entry.setWhiteListEnable(enable);
+        set_whitelist(entry, whitelist);
+        bool passed_whitelist = entry.checkCandidateUrl(candidate_url);
+        if (passed_whitelist != expected_pass)
+        {
+            message += " failed: expected ";
+            message += (expected_pass) ? "" : "NOT ";
+            message += "to match\nwhitelist = ";
+            message += whitelist;
+            message += "\ncandidate_url = ";
+            message += candidate_url;
+        }
+        ensure(message, expected_pass == passed_whitelist);
+    }
+
+    void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass)
+    {
+        whitelist_test(true, whitelist, candidate_url, expected_pass);
+    }
+    void whitelist_test(const char *whitelist, const char *candidate_url)
+    {
+        whitelist_test(true, whitelist, candidate_url, true);
+    }
+
+	template<> template<>
+	void object::test<1>()
+	{
+		set_test_name("Test LLMediaEntry Instantiation");
+		LLMediaEntry entry;
+        ensure_llsd_equals(get_test_name(), defaultMediaEntryLLSD, entry.asLLSD());
+
+	}
+
+	template<> template<>
+	void object::test<2>()
+	{
+		set_test_name("Test LLMediaEntry Instantiation from LLSD");
+        LLMediaEntry entry;
+        LLSD sd;
+        entry.fromLLSD(sd);
+        ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD());
+    }
+
+    template<> template<>
+    void object::test<3>()
+    {
+        set_test_name("Test LLMediaEntry Partial Instantiation from LLSD");
+        LLMediaEntry entry;
+        LLSD sd;
+        sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
+        entry.fromLLSD(sd);
+        LLSD golden;
+        std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com"));
+        LLSDSerialize::fromXML(golden,p);
+        ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD());
+    }
+
+    // limit tests
+    const char *URL_OK = "http://www.example.com";
+    const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
+
+    template<> template<>
+    void object::test<4>()
+    {
+        set_test_name("Test Limits on setting current URL");
+        LLMediaEntry entry;
+        U32 status = entry.setCurrentURL(URL_OK);
+        ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
+        status = entry.setCurrentURL(URL_TOO_BIG);
+        ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
+    }    
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("Test Limits on setting home URL");
+        LLMediaEntry entry;
+        U32 status = entry.setHomeURL(URL_OK);
+        ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
+        status = entry.setHomeURL(URL_TOO_BIG);
+        ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("Test Limits on setting whitelist");
+        
+        // Test a valid list
+        LLMediaEntry entry;
+        std::vector<std::string> whitelist;
+        whitelist.push_back(std::string(URL_OK));
+        S32 status = entry.setWhiteList(whitelist);
+        ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK);
+        ensure(get_test_name() + " failed", whitelist == entry.getWhiteList());
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("Test Limits on setting whitelist too big");
+        
+        // Test an invalid list
+        LLMediaEntry entry;
+        std::vector<std::string> whitelist, empty;
+        whitelist.push_back(std::string(URL_OK));
+        whitelist.push_back(std::string(URL_TOO_BIG));
+        S32 status = entry.setWhiteList(whitelist);
+        ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
+        ensure(get_test_name() + " failed", empty == entry.getWhiteList());
+    }
+
+    template<> template<>
+    void object::test<8>()
+    {
+        set_test_name("Test Limits on setting whitelist too many");
+        
+        // Test an invalid list
+        LLMediaEntry entry;
+        std::vector<std::string> whitelist, empty;
+        for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
+            whitelist.push_back("Q");
+        }
+        S32 status = entry.setWhiteList(whitelist);
+        ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
+        ensure(get_test_name() + " failed", empty == entry.getWhiteList());
+    }
+
+    template<> template<>
+    void object::test<9>()
+    {
+        set_test_name("Test to make sure both setWhiteList() functions behave the same");
+        
+        // Test a valid list
+        std::vector<std::string> whitelist, empty;
+        LLSD whitelist_llsd;
+        whitelist.push_back(std::string(URL_OK));
+        whitelist_llsd.append(std::string(URL_OK));
+        LLMediaEntry entry1, entry2;
+        ensure(get_test_name() + " setWhiteList(s) don't match",
+               entry1.setWhiteList(whitelist) == LSL_STATUS_OK &&
+               entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK );
+        ensure(get_test_name() + " failed", 
+               entry1.getWhiteList() == entry2.getWhiteList());
+    }
+    
+    template<> template<>
+    void object::test<10>()
+    {
+        set_test_name("Test to make sure both setWhiteList() functions behave the same");
+
+        // Test an invalid list
+        std::vector<std::string> whitelist, empty;
+        LLSD whitelist_llsd;
+        whitelist.push_back(std::string(URL_OK));
+        whitelist.push_back(std::string(URL_TOO_BIG));
+        whitelist_llsd.append(std::string(URL_OK));
+        whitelist_llsd.append(std::string(URL_TOO_BIG));
+        LLMediaEntry entry1, entry2;
+        ensure(get_test_name() + " setWhiteList(s) don't match",
+               entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
+               entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
+        ensure(get_test_name() + " failed", 
+               empty == entry1.getWhiteList() &&
+               empty == entry2.getWhiteList());
+    }
+
+    template<> template<>
+    void object::test<11>()
+    {
+        set_test_name("Test to make sure both setWhiteList() functions behave the same");
+
+        // Test an invalid list, too many
+        std::vector<std::string> whitelist, empty;
+        LLSD whitelist_llsd;
+        for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
+            whitelist.push_back("Q");
+            whitelist_llsd.append("Q");
+        }
+        LLMediaEntry entry1, entry2;
+        ensure(get_test_name() + " invalid result", 
+               entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
+               entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
+        ensure(get_test_name() + " failed", 
+               empty == entry1.getWhiteList() &&
+               empty == entry2.getWhiteList());
+    }
+    
+    // Whitelist check tests
+    
+    // Check the "empty whitelist" case
+    template<> template<>
+    void object::test<12>() { whitelist_test("", "http://www.example.com", true); }
+
+    // Check the "missing scheme" case
+    template<> template<>
+    void object::test<13>() { whitelist_test("www.example.com", "http://www.example.com", true); }
+
+    // Check the "exactly the same" case
+    template<> template<>
+    void object::test<14>() { whitelist_test("http://example.com", "http://example.com", true); }
+
+    // Check the enable flag
+    template<> template<>
+    void object::test<15>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); }
+    template<> template<>
+    void object::test<16>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); }
+
+    // Check permutations of trailing slash:
+    template<> template<>
+    void object::test<17>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); }
+    template<> template<>
+    void object::test<18>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); }
+    template<> template<>
+    void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); }
+    template<> template<>
+    void object::test<20>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); }
+    template<> template<>
+    void object::test<21>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); }
+
+    
+    // More cases...
+    template<> template<>
+    void object::test<22>() { whitelist_test("http://example.com", "http://example.com/wiki", true); }
+    template<> template<>
+    void object::test<23>() { whitelist_test("www.example.com", "http://www.example.com/help", true); }
+    template<> template<>
+    void object::test<24>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); }
+    template<> template<>
+    void object::test<25>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); }
+    template<> template<>
+    void object::test<26>() { whitelist_test("example.com", "http://wwwexample.com", false); }
+    template<> template<>
+    void object::test<27>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); }
+    template<> template<>
+    void object::test<28>() { whitelist_test("www.example.com", "http://www.amazon.com", false); }
+
+    // regexp cases
+    template<> template<>
+    void object::test<29>() { whitelist_test("*.example.com", "http://www.example.com", true); }
+    template<> template<>
+    void object::test<30>() { whitelist_test("*.example.com", "http://www.amazon.com", false); }
+    template<> template<>
+    void object::test<31>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); }
+    template<> template<>
+    void object::test<32>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); }
+    template<> template<>
+    void object::test<33>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); }
+    template<> template<>
+    void object::test<34>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); }
+    template<> template<>
+    void object::test<35>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); }
+    template<> template<>
+    void object::test<36>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); }
+    template<> template<>
+    void object::test<37>() { whitelist_test("http://*example.com", "http://www.example.com", true); }
+    template<> template<>
+    void object::test<38>() { whitelist_test("http://*.example.com", "http://www.example.com", true); }
+    template<> template<>
+    void object::test<39>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); }
+    template<> template<>
+    void object::test<40>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); }
+    template<> template<>
+    void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); }
+    template<> template<>
+    void object::test<42>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); }
+    template<> template<>
+    void object::test<43>() { whitelist_test("http://*.example.com", "https://www.example.com", false); }
+    template<> template<>
+    void object::test<44>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); }
+    template<> template<>
+    void object::test<45>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); }
+    template<> template<>
+    void object::test<46>() { whitelist_test("example.com", "http://www.example.com", false); }
+    template<> template<>
+    void object::test<47>() { whitelist_test("www.example.com", "http://www.example.com:80", false); }
+    template<> template<>
+    void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com", true); }
+    template<> template<>
+    void object::test<49>() { whitelist_test("www.example.com/", "http://www.example.com", false); }
+    template<> template<>
+    void object::test<50>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); }
+    // Path only
+    template<> template<>
+    void object::test<51>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); }
+    template<> template<>
+    void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); }
+}
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 1e6b216a611f47b0f7cf67064c1688c9cd2ffb10..0a284f0088be25f94d390d8b10eb2218ba1c54e8 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
     lltextbox.cpp
     lltexteditor.cpp
     lltextparser.cpp
+    lltransientfloatermgr.cpp
     lltransutil.cpp
     lltooltip.cpp
     llui.cpp
@@ -129,7 +130,7 @@ set(llui_HEADER_FILES
     llfocusmgr.h
     llfunctorregistry.h
     llhandle.h
-    llhtmlhelp.h
+    llhelp.h
     lliconctrl.h
     llkeywords.h
     lllayoutstack.h
@@ -171,6 +172,7 @@ set(llui_HEADER_FILES
     lltexteditor.h
     lltextparser.h
     lltooltip.h
+    lltransientfloatermgr.h
     lltransutil.h
     lluicolortable.h
     lluiconstants.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index fa13ced0370110fb231ec756e852b8ffc5a3b499..b9613b502c522e2a96ae1ae82a3d1997f42dcad5 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -39,7 +39,6 @@
 #include "llstring.h"
 
 // Project includes
-#include "llhtmlhelp.h"
 #include "llkeyboard.h"
 #include "llui.h"
 #include "lluiconstants.h"
@@ -49,8 +48,10 @@
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llwindow.h"
+#include "llnotifications.h"
 #include "llrender.h"
 #include "lluictrlfactory.h"
+#include "llhelp.h"
 
 static LLDefaultChildRegistry::Register<LLButton> r("button");
 
@@ -92,7 +93,6 @@ LLButton::Params::Params()
 	mouse_held_callback("mouse_held_callback"),
 	is_toggle("is_toggle", false),
 	scale_image("scale_image", true),
-	help_url("help_url"),
 	hover_glow_amount("hover_glow_amount"),
 	commit_on_return("commit_on_return", true),
 	picture_style("picture_style", false)
@@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p)
 	
 	mMouseDownTimer.stop();
 
-	if (p.help_url.isProvided())
-	{
-		setHelpURLCallback(p.help_url);
-	}
-
 	// if custom unselected button image provided...
 	if (p.image_unselected != default_params.image_unselected)
 	{
@@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
 	}
 }
 
-void clicked_help(void* data)
-{
-	LLButton* self = (LLButton*)data;
-	if (!self) return;
-	
-	if (!LLUI::sHtmlHelp)
-	{
-		return;
-	}
-	
-	LLUI::sHtmlHelp->show(self->getHelpURL());
-}
-
-void LLButton::setHelpURLCallback(const std::string &help_url)
-{
-	mHelpURL = help_url;
-	setClickedCallback(clicked_help,this);
-}
 
 // static
 void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
@@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
 	button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
 }
 
+// static
+void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
+{
+	// search back through the button's parents for a panel
+	// with a help_topic string defined
+	std::string help_topic;
+	if (LLUI::sHelpImpl &&
+	    ctrl->findHelpTopic(help_topic))
+	{
+		LLUI::sHelpImpl->showTopic(help_topic);
+		return; // success
+	}
+
+	// display an error if we can't find a help_topic string.
+	// fix this by adding a help_topic attribute to the xui file
+	LLNotifications::instance().add("UnableToFindHelpTopic");
+}
+
 void LLButton::resetMouseDownTimer()
 {
 	mMouseDownTimer.stop();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 06e1dac914b7a6e43813e42a2f21af36f8f780eb..04716d605b9d1d9cd54c197dfdeca311b7d29cba 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -118,7 +118,6 @@ class LLButton
 								commit_on_return,
 								picture_style;      //if true, don't display label
 		
-		Optional<std::string>		help_url;
 		Optional<F32>				hover_glow_amount;
 		Optional<TimeIntervalParam>	held_down_delay;
 
@@ -230,12 +229,10 @@ class LLButton
 	void			setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
 	BOOL			getCommitOnReturn() const { return mCommitOnReturn; }
 
-	void			setHelpURLCallback(const std::string &help_url);
-	const std::string&	getHelpURL() const { return mHelpURL; }
-
 	static void		onHeldDown(void *userdata);  // to be called by gIdleCallbacks
 	static void		toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
 	static void		setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
+	static void		showHelp(LLUICtrl* ctrl, const LLSD& sdname);
 	
 protected:
 	const LLPointer<LLUIImage>&	getImageUnselected() const	{ return mImageUnselected; }
@@ -314,8 +311,6 @@ class LLButton
 	BOOL						mCommitOnReturn;
 	BOOL						mFadeWhenDisabled;
 
-	std::string					mHelpURL;
-
 	LLFrameTimer				mFlashingTimer;
 };
 
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 58aeb617287195739308669860c883f3757efeb2..0170ac0c6acf086a0cd7f3e7f7a8e5c2bf227e9f 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
 		params.max_length_bytes(mMaxChars);
 		params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
 		params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
-		params.focus_lost_callback(NULL);
 		params.handle_edit_keys_directly(true);
 		params.commit_on_focus_lost(false);
 		params.follows.flags(FOLLOWS_ALL);
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 93d62fd7c2e2456031e5c78913542609db3d9595..4525f0a45b47a5dee3f2ad9483084f04e2a5e20f 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
 		if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
 		{
 			sInstanceHandle.get()->setVisible(FALSE);
-			}
+		}
 		sInstanceHandle = getHandle();
-			}
+	}
 }
 
 void LLDockableFloater::setVisible(BOOL visible)
@@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
 			mDockControl.get()->off();
 		}
 
-	if (!docked && pop_on_undock)
-	{
-		// visually pop up a little bit to emphasize the undocking
-		translate(0, UNDOCK_LEAP_HEIGHT);
-	}
+		if (!docked && pop_on_undock)
+		{
+			// visually pop up a little bit to emphasize the undocking
+			translate(0, UNDOCK_LEAP_HEIGHT);
+		}
 	}
 	else
 	{
@@ -126,8 +126,8 @@ void LLDockableFloater::draw()
 		mDockControl.get()->repositionDockable();
 		if (isDocked())
 		{
-		mDockControl.get()->drawToungue();
-	}
+			mDockControl.get()->drawToungue();
+		}
 	}
 	LLFloater::draw();
 }
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 0b16b2554c4db7cc7ed056f584ed106ad18f8c2e..146c7a969a0abd6de9c733c0243cce2d886f78b5 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,7 +35,7 @@
 #include "lldockcontrol.h"
 
 LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-		const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
+		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
 		mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)		
 {
 	mDockAt = dockAt;
@@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		off();
 	}
 
-	if (!(get_rect_callback))
+	if (!(get_allowed_rect_callback))
 	{
-		mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
+		mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
 	}
 	else
 	{
-		mGetRectCallback = get_rect_callback;
+		mGetAllowedRectCallback = get_allowed_rect_callback;
 	}
 
 	if (dockWidget != NULL) 
@@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
 	}
 }
 
-void LLDockControl::getEnabledRect(LLRect& rect)
+void LLDockControl::getAllowedRect(LLRect& rect)
 {
 	rect = mDockableFloater->getRootView()->getRect();
 }
@@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
 {
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 	static BOOL prev_visibility = !mDockWidget->getVisible();
 
 	// recalculate dockable position if dock position changed, dock visibility changed,
@@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
 			mDockableFloater->setDocked(false);
 			// force off() since dockable may not have dockControll at this time
 			off();
-	}
+		}
 		else
 		{
 			moveDockable();
@@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
 		res = mDockWidget->isInVisibleChain();
 		if (res)
 		{
-	LLRect dockRect = mDockWidget->calcScreenRect();
+			LLRect dockRect = mDockWidget->calcScreenRect();
 
 			switch (mDockAt)
-	{
+			{
 			case TOP:
 				// check is dock inside parent rect
 				LLRect dockParentRect =
@@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
 	// calculate new dockable position
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 
-		LLRect dockableRect = mDockableFloater->calcScreenRect();
-		S32 x = 0;
-		S32 y = 0;
-		switch (mDockAt)
-		{
-		case TOP:
-			x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+	LLRect dockableRect = mDockableFloater->calcScreenRect();
+	S32 x = 0;
+	S32 y = 0;
+	switch (mDockAt)
+	{
+	case TOP:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
 		y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.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();
-			}
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
 
 
 		// calculate dock tongue position
@@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
 		{
 			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
 		}
-			mDockTongueY = dockRect.mTop;
+		mDockTongueY = dockRect.mTop;
 
-			break;
-		}
+		break;
+	}
 
 	// move dockable
-		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
-				dockableRect.getHeight());
-		LLRect localDocableParentRect;
-		mDockableFloater->getParent()->screenRectToLocal(dockableRect,
-				&localDocableParentRect);
-		mDockableFloater->setRect(localDocableParentRect);
+	dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+			dockableRect.getHeight());
+	LLRect localDocableParentRect;
+	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+			&localDocableParentRect);
+	mDockableFloater->setRect(localDocableParentRect);
 
-		mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
-				&mDockTongueX, &mDockTongueY);
+	mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+			&mDockTongueX, &mDockTongueY);
 
 }
 
@@ -207,9 +207,9 @@ void LLDockControl::on()
 {
 	 if (isDockVisible())
 	{
-	mDockableFloater->setCanDrag(false);
-	mEnabled = true;
-	mRecalculateDocablePosition = true;
+		mDockableFloater->setCanDrag(false);
+		mEnabled = true;
+		mRecalculateDocablePosition = true;
 	}
 }
 
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 219ddfd09256a62556b9fc682bc285b3cf051b17..e8ffcac0ac95165b08b7333d39af53fcf08b2e17 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -52,11 +52,11 @@ class LLDockControl
 
 public:
 	// callback for a function getting a rect valid for control's position
-	typedef boost::function<void (LLRect& )> get_rect_callback_t;
+	typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
 
 	LOG_CLASS(LLDockControl);
 	LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-			const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
+			const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
 	virtual ~LLDockControl();
 
 public:
@@ -67,13 +67,13 @@ class LLDockControl
 	void drawToungue();
 	bool isDockVisible();
 
-	// gets a rect that bounds possible positions for a dockable control
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for a dockable control (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 
 private:
 	virtual void moveDockable();
 private:
-	get_rect_callback_t mGetRectCallback;
+	get_allowed_rect_callback_t mGetAllowedRectCallback;
 	bool mEnabled;
 	bool mRecalculateDocablePosition;
 	DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9fcd386c193e0476532577490e727d3de7a32799..e9df36147264bdc2daa75d707a03cab1424dedee 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
 
 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);
+const LLSD SELECTED_EVENT	= LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT	= LLSD().insert("selected", false);
 
 static const std::string COMMENT_TEXTBOX = "comment_text";
 
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 81915731c3835b52446a3a30c872170688007cef..ff0288a32f0eedc16ffa0b41dd9c633c10fd159c 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -59,6 +59,7 @@
 #include "lltabcontainer.h"
 #include "v2math.h"
 #include "lltrans.h"
+#include "llhelp.h"
 #include "llmultifloater.h"
 
 // use this to control "jumping" behavior when Ctrl-Tabbing
@@ -66,48 +67,35 @@ const S32 TABBED_FLOATER_OFFSET = 0;
 
 std::string	LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = 
 {
-	"Icon_Close_Foreground",		//BUTTON_CLOSE
-	"restore.tga",	//BUTTON_RESTORE
-	"minimize.tga",	//BUTTON_MINIMIZE
-	"tearoffbox.tga",	//BUTTON_TEAR_OFF
-	"closebox.tga",		//BUTTON_EDIT
-	"Icon_Dock_Foreground",
-	"Icon_Undock_Foreground"
-};
-
-// Empty string means programmatic glow effect, achieved by
-// not setting explicit image.
-std::string	LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] = 
-{
-	"",						//BUTTON_CLOSE
-	"restore_pressed.tga",	//BUTTON_RESTORE
-	"minimize_pressed.tga",	//BUTTON_MINIMIZE
-	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF
-	"close_in_blue.tga",	//BUTTON_EDIT
-	"",						//BUTTON_DOCK
-	"",						//BUTTON_UNDOCK
+	"Icon_Close_Foreground",	//BUTTON_CLOSE
+	"Icon_Restore_Foreground",	//BUTTON_RESTORE
+	"Icon_Minimize_Foreground",	//BUTTON_MINIMIZE
+	"tearoffbox.tga",			//BUTTON_TEAR_OFF
+	"Icon_Dock_Foreground",		//BUTTON_DOCK
+	"Icon_Undock_Foreground",	//BUTTON_UNDOCK
+	"Icon_Help_Foreground"		//BUTTON_HELP
 };
 
 std::string	LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = 
 {
-	"Icon_Close_Press",		//BUTTON_CLOSE
-	"restore_pressed.tga",	//BUTTON_RESTORE
-	"minimize_pressed.tga",	//BUTTON_MINIMIZE
-	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF
-	"close_in_blue.tga",		//BUTTON_EDIT
-	"Icon_Dock_Press",
-	"Icon_Undock_Press"
+	"Icon_Close_Press",			//BUTTON_CLOSE
+	"Icon_Restore_Press",		//BUTTON_RESTORE
+	"Icon_Minimize_Press",		//BUTTON_MINIMIZE
+	"tearoff_pressed.tga",		//BUTTON_TEAR_OFF
+	"Icon_Dock_Press",			//BUTTON_DOCK
+	"Icon_Undock_Press",		//BUTTON_UNDOCK
+	"Icon_Help_Press"			//BUTTON_HELP
 };
 
 std::string	LLFloater::sButtonNames[BUTTON_COUNT] = 
 {
-	"llfloater_close_btn",	//BUTTON_CLOSE
+	"llfloater_close_btn",		//BUTTON_CLOSE
 	"llfloater_restore_btn",	//BUTTON_RESTORE
 	"llfloater_minimize_btn",	//BUTTON_MINIMIZE
 	"llfloater_tear_off_btn",	//BUTTON_TEAR_OFF
-	"llfloater_edit_btn",		//BUTTON_EDIT
-	"llfloater_dock_btn",
-	"llfloater_undock_btn"
+	"llfloater_dock_btn",		//BUTTON_DOCK
+	"llfloater_undock_btn",		//BUTTON_UNDOCK
+	"llfloater_help_btn"		//BUTTON_HELP
 };
 
 std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
@@ -122,9 +110,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
 	"BUTTON_RESTORE",		//"Restore",	//BUTTON_RESTORE
 	"BUTTON_MINIMIZE",		//"Minimize",	//BUTTON_MINIMIZE
 	"BUTTON_TEAR_OFF",		//"Tear Off",	//BUTTON_TEAR_OFF
-	"BUTTON_EDIT",			//"Edit",		//BUTTON_EDIT
 	"BUTTON_DOCK",
-	"BUTTON_UNDOCK"
+	"BUTTON_UNDOCK",
+	"BUTTON_HELP"
 };
 
 LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -133,13 +121,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
 	LLFloater::onClickMinimize, //BUTTON_RESTORE
 	LLFloater::onClickMinimize, //BUTTON_MINIMIZE
 	LLFloater::onClickTearOff,	//BUTTON_TEAR_OFF
-	LLFloater::onClickEdit,	//BUTTON_EDIT
-	LLFloater::onClickDock,
-	LLFloater::onClickDock
+	LLFloater::onClickDock,		//BUTTON_DOCK
+	LLFloater::onClickDock,		//BUTTON_UNDOCK
+	LLFloater::onClickHelp		//BUTTON_HELP
 };
 
 LLMultiFloater* LLFloater::sHostp = NULL;
-BOOL			LLFloater::sEditModeEnabled = FALSE;
 BOOL			LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
 LLFloater::handle_map_t	LLFloater::sFloaterMap;
 
@@ -259,7 +246,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	mMinimized(FALSE),
 	mForeground(FALSE),
 	mFirstLook(TRUE),
-	mEditing(FALSE),
 	mButtonScale(1.0f),
 	mAutoFocus(TRUE), // automatically take focus when opened
 	mCanDock(false),
@@ -314,6 +300,12 @@ void LLFloater::initFloater()
 		mButtonsEnabled[BUTTON_CLOSE] = TRUE;
 	}
 
+	// Help button: '?'
+	if ( !mHelpTopic.empty() )
+	{
+		mButtonsEnabled[BUTTON_HELP] = TRUE;
+	}
+
 	// Minimize button only for top draggers
 	if ( !mDragOnLeft && mCanMinimize )
 	{
@@ -804,7 +796,7 @@ void LLFloater::setTitle( const std::string& title )
 	applyTitle();
 }
 
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
 {
 	if (mTitle.empty())
 	{
@@ -822,7 +814,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
 	applyTitle();
 }
 
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
 {
 	if (mShortTitle.empty())
 	{
@@ -834,8 +826,6 @@ std::string LLFloater::getShortTitle()
 	}
 }
 
-
-
 BOOL LLFloater::canSnapTo(const LLView* other_view)
 {
 	if (NULL == other_view)
@@ -1051,6 +1041,10 @@ void LLFloater::setMinimized(BOOL minimize)
 		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
 	}
 	
+	// don't show the help button while minimized - it's
+	// not very useful when minimized and uses up space
+	mButtonsEnabled[BUTTON_HELP] = !minimize;
+
 	applyTitle ();
 
 	make_ui_sound("UISndWindowClose");
@@ -1387,28 +1381,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
 	}
 }
 
-//static
-void LLFloater::setEditModeEnabled(BOOL enable)
-{
-	if (enable != sEditModeEnabled)
-	{
-		S32 count = 0;
-		for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
-		{
-			LLFloater* floater = iter->second;
-			if (!floater->isDead())
-			{
-				iter->second->mButtonsEnabled[BUTTON_EDIT] = enable;
-				iter->second->updateButtons();
-			}
-			count++;
-		}
-	}
-
-	sEditModeEnabled = enable;
-}
-
-
 // static
 void LLFloater::onClickMinimize(LLFloater* self)
 {
@@ -1456,19 +1428,20 @@ void LLFloater::onClickTearOff(LLFloater* self)
 }
 
 // static
-void LLFloater::onClickEdit(LLFloater* self)
+void LLFloater::onClickDock(LLFloater* self)
 {
-	if (!self)
-		return;
-	self->mEditing = self->mEditing ? FALSE : TRUE;
+	if(self && self->mCanDock)
+	{
+		self->setDocked(!self->mDocked, true);
+	}
 }
 
 // static
-void LLFloater::onClickDock(LLFloater* self)
+void LLFloater::onClickHelp( LLFloater* self )
 {
-	if(self && self->mCanDock)
+	if (self && LLUI::sHelpImpl)
 	{
-		self->setDocked(!self->mDocked, true);
+		LLUI::sHelpImpl->showTopic(self->getHelpTopic());
 	}
 }
 
@@ -1807,17 +1780,9 @@ void LLFloater::buildButtons()
 		// Selected, no matter if hovered or not, is "pressed"
 		p.image_selected.name(sButtonPressedImageNames[i]);
 		p.image_hover_selected.name(sButtonPressedImageNames[i]);
-		// Empty string means programmatic glow effect, achieved by
-		// not setting explicit image.
-		if (sButtonHoveredImageNames[i].empty())
-		{
-			// These icons are really small, need glow amount increased
-			p.hover_glow_amount( 0.22f );
-		}
-		else
-		{
-			p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
-		}
+		// Use a glow effect when the user hovers over the button
+		// These icons are really small, need glow amount increased
+		p.hover_glow_amount( 0.33f );
 		p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
 		p.tab_stop(false);
 		p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 513f6a69180dd6f8bf6776ddf12e1ff9d30aed14..2a31ba4e8f8e00d54f0beed2b7db983f774681dd 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -101,9 +101,9 @@ friend class LLMultiFloater;
 		BUTTON_RESTORE,
 		BUTTON_MINIMIZE,
 		BUTTON_TEAR_OFF,
-		BUTTON_EDIT,
 		BUTTON_DOCK,
 		BUTTON_UNDOCK,
+		BUTTON_HELP,
 		BUTTON_COUNT
 	};
 	
@@ -173,9 +173,9 @@ friend class LLMultiFloater;
 	void			applyTitle();
 	const std::string&	getCurrentTitle() const;
 	void			setTitle( const std::string& title);
-	std::string		getTitle();
+	std::string		getTitle() const;
 	void			setShortTitle( const std::string& short_title );
-	std::string		getShortTitle();
+	std::string		getShortTitle() const;
 	void			setTitleVisible(bool visible);
 	virtual void	setMinimized(BOOL b);
 	void			moveResizeHandlesToFront();
@@ -256,12 +256,10 @@ friend class LLMultiFloater;
 	static void		onClickClose(LLFloater* floater);
 	static void		onClickMinimize(LLFloater* floater);
 	static void		onClickTearOff(LLFloater* floater);
-	static void		onClickEdit(LLFloater* floater);
 	static void     onClickDock(LLFloater* floater);
+	static void		onClickHelp(LLFloater* floater);
 
 	static void		setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
-	static void		setEditModeEnabled(BOOL enable);
-	static BOOL		getEditModeEnabled() { return sEditModeEnabled; }
 	static LLMultiFloater* getFloaterHost() {return sHostp; }
 		
 protected:
@@ -331,7 +329,6 @@ friend class LLMultiFloater;
 	
 
 	BOOL			mFirstLook;			// TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
-	BOOL			mEditing;
 	
 	typedef std::set<LLHandle<LLFloater> > handle_set_t;
 	typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
@@ -350,11 +347,8 @@ friend class LLMultiFloater;
 	bool            mDocked;
 
 	static LLMultiFloater* sHostp;
-	static BOOL		sEditModeEnabled;
 	static BOOL		sQuitting;
 	static std::string	sButtonActiveImageNames[BUTTON_COUNT];
-	// Images to use when cursor hovered over an enabled button
-	static std::string	sButtonHoveredImageNames[BUTTON_COUNT];
 	static std::string	sButtonPressedImageNames[BUTTON_COUNT];
 	static std::string	sButtonNames[BUTTON_COUNT];
 	static std::string	sButtonToolTips[BUTTON_COUNT];
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index ab9b59e2526efda611c7e6fefe3df611c3048067..279cbaa923506c213b6a4322d513df68a756e048 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f;
 // NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
 
 LLFocusableElement::LLFocusableElement()
-:	mFocusLostCallback(NULL),
-	mFocusReceivedCallback(NULL),
-	mFocusChangedCallback(NULL),
-	mTopLostCallback(NULL),
-	mFocusCallbackUserData(NULL)
 {
 }
 
@@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement()
 
 void LLFocusableElement::onFocusReceived()
 {
-	if( mFocusReceivedCallback )
-	{
-		mFocusReceivedCallback( this, mFocusCallbackUserData );
-	}
-	if( mFocusChangedCallback )
-	{
-		mFocusChangedCallback( this, mFocusCallbackUserData );
-	}
+	mFocusReceivedCallback(this);
+	mFocusChangedCallback(this);
 }
 
 void LLFocusableElement::onFocusLost()
 {
-	if( mFocusLostCallback )
-	{
-		mFocusLostCallback( this, mFocusCallbackUserData );
-	}
-
-	if( mFocusChangedCallback )
-	{
-		mFocusChangedCallback( this, mFocusCallbackUserData );
-	}
+	mFocusLostCallback(this);
+	mFocusChangedCallback(this);
 }
 
 void LLFocusableElement::onTopLost()
 {
-	if (mTopLostCallback)
-	{
-		mTopLostCallback(this, mFocusCallbackUserData);
-	}
+	mTopLostCallback(this);
 }
 
 BOOL LLFocusableElement::hasFocus() const
@@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
 		view_handle_list_t new_focus_list;
 
 		// walk up the tree to root and add all views to the new_focus_list
-		for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
+		for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
 		{
-			if (ctrl) 
-			{
-				new_focus_list.push_back(ctrl->getHandle());
-			}
+			new_focus_list.push_back(ctrl->getHandle());
 		}
 
 		// remove all common ancestors since their focus is unchanged
@@ -216,10 +192,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
 			{
 				mCachedKeyboardFocusList.pop_front();
 				old_focus_view->onFocusLost();
-
-				// part of fix of EXT-996
-				// this need to handle event when user click inside in-world area
-				mFocusChangeSignal();
 			}
 		}
 
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 2c2dae216a90b5b0961919fa2c753752d2120e09..2fa4e124fb8c8fedba410114a22f03dbf04faa07 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -54,11 +54,12 @@ class LLFocusableElement
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	hasFocus() const;
 
-	typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
-	void	setFocusLostCallback(focus_callback_t cb, void* user_data = NULL)	{ mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL)	{ mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL )	{ mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setTopLostCallback(focus_callback_t cb, void* user_data = NULL )	{ mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
+	typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
+	
+	boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb)	{ return mFocusLostCallback.connect(cb);}
+	boost::signals2::connection	setFocusReceivedCallback(const focus_signal_t::slot_type& cb)	{ return mFocusReceivedCallback.connect(cb);}
+	boost::signals2::connection	setFocusChangedCallback(const focus_signal_t::slot_type& cb)	{ return mFocusChangedCallback.connect(cb);}
+	void	setTopLostCallback(const focus_signal_t::slot_type& cb)	{ mTopLostCallback.connect(cb);}
 
 	// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
 	virtual BOOL	handleKey(KEY key, MASK mask, BOOL called_from_parent);
@@ -68,11 +69,10 @@ class LLFocusableElement
 	virtual void	onFocusReceived();
 	virtual void	onFocusLost();
 	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere
-	focus_callback_t mFocusLostCallback;
-	focus_callback_t mFocusReceivedCallback;
-	focus_callback_t mFocusChangedCallback;
-	focus_callback_t mTopLostCallback;
-	void*			mFocusCallbackUserData;
+	focus_signal_t  mFocusLostCallback;
+	focus_signal_t  mFocusReceivedCallback;
+	focus_signal_t  mFocusChangedCallback;
+	focus_signal_t  mTopLostCallback;
 };
 
 
@@ -124,11 +124,6 @@ class LLFocusMgr
 	void			unlockFocus();
 	BOOL			focusLocked() const { return mLockedView != NULL; }
 
-	void			addFocusChangeCallback(const boost::signals2::signal<void ()>::slot_type& cb)
-	{
-		mFocusChangeSignal.connect(cb);
-	}
-
 private:
 	LLUICtrl*			mLockedView;
 
@@ -155,8 +150,6 @@ class LLFocusMgr
 	typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
 	focus_history_map_t mFocusHistory;
 
-	boost::signals2::signal<void()>	mFocusChangeSignal;
-
 	#ifdef _DEBUG
 		std::string		mMouseCaptorName;
 		std::string		mKeyboardFocusName;
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
new file mode 100644
index 0000000000000000000000000000000000000000..c06d29a4bd497203df318238157ab8a2dacc62dd
--- /dev/null
+++ b/indra/llui/llhelp.h
@@ -0,0 +1,45 @@
+/** 
+ * @file llhelp.h
+ * @brief Abstract interface to the Help system
+ * @author Tofu Linden
+ *
+ * $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_LLHELP_H
+#define LL_LLHELP_H
+
+class LLHelp
+{
+ public:
+	virtual void showTopic(const std::string &topic) = 0;
+	// return default (fallback) topic name suitable for showTopic()
+	virtual std::string defaultTopic() = 0;
+};
+
+#endif // headerguard
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 01a3b5fdc795263aa118b33b35ea8cadcff8024b..0fbb7ced54fa5ab2cb565358176d720ca061c0b3 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
 			params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 			params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 			mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
-			mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
+			mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
 			// don't do this, as selecting the entire text is single clicking in some cases
 			// and double clicking in others
 			//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 26136e0a231c8f6a7cbbe58289284afd1cb25e89..b9bbb4db22fcd8635480717adef61a42c59f67fd 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -80,6 +80,7 @@ LLPanel::Params::Params()
 	strings("string"),
 	filename("filename"),
 	class_name("class"),
+	help_topic("help_topic"),
 	visible_callback("visible_callback")
 {
 	name = "panel";
@@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
 	mDefaultBtn(NULL),
 	mBorder(NULL),
 	mLabel(p.label),
+	mHelpTopic(p.help_topic),
 	mCommitCallbackRegistrar(false),
 	mEnableCallbackRegistrar(false),
 	mXMLFilename(p.filename)
@@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
 	}
 
 	setLabel(p.label());
+	setHelpTopic(p.help_topic);
 	setShape(p.rect);
 	parseFollowsFlags(p);
 
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 81b5b68f05e9c471fed28840e80557dd32bfc702..8b23ea7030bbac31b7705cba4aef18de96287aec 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -83,6 +83,7 @@ class LLPanel : public LLUICtrl
 
 		Optional<std::string>	filename;
 		Optional<std::string>	class_name;
+		Optional<std::string>   help_topic;
 
 		Multiple<LocalizedString>	strings;
 		
@@ -139,10 +140,11 @@ class LLPanel : public LLUICtrl
 	void			updateDefaultBtn();
 	void			setLabel(const LLStringExplicit& label) { mLabel = label; }
 	std::string		getLabel() const { return mLabel; }
+	void			setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; }
+	std::string		getHelpTopic() const { return mHelpTopic; }
 	
 	void			setCtrlsEnabled(BOOL b);
 
-
 	LLHandle<LLPanel>	getHandle() const { return mPanelHandle; }
 
 	const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@@ -243,6 +245,8 @@ class LLPanel : public LLUICtrl
 	EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
 	
 	commit_signal_t mVisibleSignal;		// Called when visibility changes, passes new visibility as LLSD()
+
+	std::string		mHelpTopic;         // the name of this panel's help topic to display in the Help Viewer
 	
 private:
 	LLUIColor		mBgColorAlpha;
@@ -259,7 +263,7 @@ class LLPanel : public LLUICtrl
 
 	// for setting the xml filename when building panel in context dependent cases
 	std::string		mXMLFilename;
-	
+
 }; // end class LLPanel
 
 #endif
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 7e72331a3faa1b5c4ffa27c17e23850fe015566f..7e88b16561cd4594cdca01a999b70d6c3cfbb981 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -130,12 +130,6 @@ class LLScrollbar
 	void				onLineUpBtnPressed(const LLSD& data);
 	void				onLineDownBtnPressed(const LLSD& data);
 
-	void				setBGColor(const LLUIColor& color) { mBGColor = color; }
-	const LLUIColor&	getBGColor() const { return mBGColor; }
-
-	void				setBGVisible() { mBGVisible = true; }
-	bool				getBGVisible() const { return mBGVisible; }
-
 private:
 	void				updateThumbRect();
 	void				changeLine(S32 delta, BOOL update_thumb );
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 15584c8dc7d62725d27adfa0d199463e9cde762e..fb71b607258f1279e23f4d5ec79b6ad86e82a581 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 			line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 			mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
 
-			mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
+			mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
 			// don't do this, as selecting the entire text is single clicking in some cases
 			// and double clicking in others
 			//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 3a96bc8f937df2e758e1e950f516a5d2879c32fa..83d71006aacaf6e0c9903677193b907b4d4c6964 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 	params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 	mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
-	mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
+	mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
 	//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
 	// than when it doesn't.  Instead, if you always have to double click to select all the text, 
 	// it's easier to understand
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59eb88ee5c1a3507dced1675d34d4df2..39f09b297f5a759d84f53d1c97d565afd52e53fb 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
 	deleteSelection( FALSE );
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
 	deselect();
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
 		if(text_may_have_changed)
 		{
 			needsReflow();
+
+			onKeyStroke();
 		}
 		needsScroll();
 	}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 		deselect();
 
 		needsReflow();
+
+		onKeyStroke();
 	}
 
 	return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
 			setCursorPos(mCursorPos + 1);
 			removeChar();
 		}
+
+		onKeyStroke();
 	}
 
 	needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
 
 	// Update of the preedit should be caused by some key strokes.
 	mKeystrokeTimer.reset();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
 		ed->addDocumentChild(mView);
 	}
 }
+
+BOOL LLTextEditor::isDirty() const
+{
+	if(mReadOnly)
+	{
+		return FALSE;
+	}
+
+	if( mPristineCmd )
+	{
+		return ( mPristineCmd == mLastCmd );
+	}
+	else
+	{
+		return ( NULL != mLastCmd );
+	}
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+	mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+	mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1bb4009f7432137a82fb6063bcf3ae9..a04261c4be96b116ba3e29b69833fa0a44d5f951 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ class LLTextEditor :
 
 	virtual ~LLTextEditor();
 
+	typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+	void	setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
 	void	setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
 
 	// mousehandler overrides
@@ -169,7 +173,7 @@ class LLTextEditor :
 	virtual void	clear();
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	acceptsTextInput() const;
-	virtual BOOL	isDirty() const { return isPristine(); }
+	virtual BOOL	isDirty() const;
 	virtual void 	setValue(const LLSD& value);
 
 	// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ class LLTextEditor :
 
 	S32				getFirstVisibleLine() const;
 
+	void			onKeyStroke();
+
 	//
 	// Data
 	//
@@ -568,6 +574,8 @@ class LLTextEditor :
 	BOOL			mHandleEditKeysDirectly;  
 
 	LLCoordGL		mLastIMEPosition;		// Last position of the IME editor
+
+	keystroke_signal_t mKeystrokeSignal;
 }; // end class LLTextEditor
 
 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 000e85f78c4ea2a8ff690359eb4d2be431e734b1..d5b67f53b76055e14eaf075b096a2dc1b27b6925 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -79,10 +79,10 @@ std::list<std::string> gUntranslated;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
 /*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
-/*static*/ LLHtmlHelp*		LLUI::sHtmlHelp = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
-/*static*/ BOOL				LLUI::sDirty = FALSE;
-/*static*/ LLRect			LLUI::sDirtyRect;
+/*static*/ BOOL                         LLUI::sDirty = FALSE;
+/*static*/ LLRect                       LLUI::sDirtyRect;
+/*static*/ LLHelp*			LLUI::sHelpImpl = NULL;
 /*static*/ std::vector<std::string> LLUI::sXUIPaths;
 /*static*/ LLFrameTimer		LLUI::sMouseIdleTimer;
 
@@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 }
 
 
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	LLGLSUIDefault gls_ui;
-
-	gGL.pushMatrix();
-	{
-		gGL.translatef((F32)x, (F32)y, 0.f);
-
-		gGL.getTexUnit(0)->bind(image);
-
-		gGL.color4fv(color.mV);
-		
-		gGL.begin(LLRender::QUADS);
-		{
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
-			gGL.vertex2i(width, height );
-
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
-			gGL.vertex2i(0, height );
-
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
-			gGL.vertex2i(0, 0);
-
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
-			gGL.vertex2i(width, 0);
-		}
-		gGL.end();
-	}
-	gGL.popMatrix();
-}
-
-
 void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
 {
 	phase = fmod(phase, 1.f);
@@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings,
 	// Button initialization callback for toggle buttons
 	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
 	
+	// Display the help topic for the current context
+	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
+
 	// Currently unused, but kept for reference:
 	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
 	
@@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
 		return NULL;
 }
 
-// static 
-void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
-{
-	LLUI::sHtmlHelp = html_help;
-}
-
 LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 {
 	for (settings_map_t::iterator itor = sSettingGroups.begin();
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index fddf8192ade459720708ae423fc5e64bbf153339..86cb51650089268c57570b94f8ebb9e950e35966 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -57,13 +57,13 @@
 #include "llfontgl.h"
 
 class LLColor4; 
-class LLHtmlHelp;
 class LLVector3;
 class LLVector2;
 class LLUIImage;
 class LLUUID;
 class LLWindow;
 class LLView;
+class LLHelp;
 
 // UI colors
 extern const LLColor4 UI_VERTEX_COLOR;
@@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
 void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-// Flip vertical, used for LLFloaterHTML
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 
 void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
 void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
@@ -203,7 +201,6 @@ class LLUI
 	static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
 	static void screenRectToGL(const LLRect& screen, LLRect *gl);
 	static void glRectToScreen(const LLRect& gl, LLRect *screen);
-	static void setHtmlHelp(LLHtmlHelp* html_help);
 	// Returns the control group containing the control name, or the default group
 	static LLControlGroup& getControlControlGroup (const std::string& controlname);
 	static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
@@ -223,8 +220,8 @@ class LLUI
 	static LLUIAudioCallback sAudioCallback;
 	static LLVector2		sGLScaleFactor;
 	static LLWindow*		sWindow;
-	static LLHtmlHelp*		sHtmlHelp;
 	static LLView*			sRootView;
+	static LLHelp*			sHelpImpl;
 private:
 	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 8807e26f6b3cb7eca84c5850c838ea30de58d228..fe99d9c2672412f1e55c9b4a846d5159146d1787 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p)
 	}
 
 	setTabStop(p.tab_stop);
-	setFocusLostCallback(p.focus_lost_callback());
 
 	if (p.initial_value.isProvided() 
 		&& !p.control_name.isProvided())
@@ -763,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
 	return NULL;
 }
 
+bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
+{
+	LLUICtrl* ctrl = this;
+
+	// search back through the control's parents for a panel
+	// with a help_topic string defined
+	while (ctrl)
+	{
+		LLPanel *panel = dynamic_cast<LLPanel *>(ctrl);
+		if (panel && !panel->getHelpTopic().empty())
+		{
+			help_topic_out = panel->getHelpTopic();
+			return true; // success
+		}
+		
+		ctrl = ctrl->getParentUICtrl();
+	}
+
+	return false; // no help topic found
+}
+
 // *TODO: Deprecate; for backwards compatability only:
 boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
 {
@@ -800,14 +820,7 @@ namespace LLInitParam
     	return false;
     }
     
-    template<> 
-	bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
-		const LLUICtrl::focus_callback_t &a, 
-		const LLUICtrl::focus_callback_t &b)
-    {
-    	return false;
-    }
-    
+   
     template<> 
 	bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
 		const LLUICtrl::enable_callback_t &a, 
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3add9393ea605059f6ec032fdd767ab8c5da98d2..c2502732f375a9ac0c96c51d51bab7511377770b 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -124,8 +124,6 @@ class LLUICtrl
 		Optional<CommitCallbackParam>	mouseenter_callback;
 		Optional<CommitCallbackParam>	mouseleave_callback;
 		
-		Optional<focus_callback_t>		focus_lost_callback;
-		
 		Optional<std::string>			control_name;
 		Optional<EnableControls>		enabled_controls;
 		Optional<ControlVisibility>		controls_visibility;
@@ -225,6 +223,10 @@ class LLUICtrl
 
 	LLUICtrl*		getParentUICtrl() const;
 
+	// return true if help topic found by crawling through parents -
+	// topic then put in help_topic_out
+	bool                    findHelpTopic(std::string& help_topic_out);
+
 	boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
 	boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
 
@@ -309,11 +311,6 @@ namespace LLInitParam
 		const LLUICtrl::enable_callback_t &a, 
 		const LLUICtrl::enable_callback_t &b); 
     
-	template<> 
-	bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
-		const LLUICtrl::focus_callback_t &a, 
-		const LLUICtrl::focus_callback_t &b); 
-	
     template<>
 	bool ParamCompare<LLLazyValue<LLColor4> >::equals(
 		const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); 
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 3b689b93c0af66d39ea6a2a5eac8e8d5dd8f7170..f3401f91f7a5435ba518c4c6b79d3499cfa5e51f 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
 		LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
 	}	
 }
-
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 256c7762934e6b826b6b11e678634a8a9860e03b..10cb3fb37702dd50ccc3da40f0b97ecfd65d47b3 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect()
 	return mRect;
 }
 
-//virtual
-void LLView::onFocusLost()
-{
-}
-
-//virtual
-void LLView::onFocusReceived()
-{
-}
-
 BOOL LLView::focusNextRoot()
 {
 	LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index bf3b5d0614e02f9171e9b84c83016209b8018656..7a37d6f4303cf23fe31ae1524bf2a1bc0dba0c9b 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -405,10 +405,6 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 	BOOL getSaveToXML() const { return mSaveToXML; }
 	void setSaveToXML(BOOL b) { mSaveToXML = b; }
 
-	// inherited from LLFocusableElement
-	/* virtual */ void onFocusLost();
-	/* virtual */ void onFocusReceived();
-
 	typedef enum e_hit_test_type
 	{
 		HIT_TEST_USE_BOUNDING_RECT,
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 24efcb8ae848fc6de12aa17e0cebdedfdbf4b013..7a531e0fbff99582865030fed2a20feb03b79136 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -383,7 +383,7 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const
 
 /*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
 {
-	return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+	return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
 		"SLPlugin";
 }
 
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 9be787df11fc02deec4d9c4c6619bacfacdd8890..346f7dd8ed762f668185b956cc7b4837f6f9c95b 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -424,7 +424,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
 
 /*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
 {
-	return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+	return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
 		"SLPlugin";
 }
 
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 872f2cf1c1fdbf7e28d50167ba8f23d5ea06687b..3e302764de288453c4e2266b2469607d718fb608 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -397,7 +397,7 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const
 
 /*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
 {
-	return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+	return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
 		"SLPlugin.exe";
 }
 
diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt
index 252085bab2d0f4da05a4b906906dd2298bd246ff..3ed2892e0ed55ecca656b24ba15f04c22cdf7f9d 100644
--- a/indra/lscript/lscript_compile/CMakeLists.txt
+++ b/indra/lscript/lscript_compile/CMakeLists.txt
@@ -5,6 +5,7 @@ include(LLCommon)
 include(LLMath)
 include(LLMessage)
 include(LLInventory)
+include(LLPrimitive)
 include(LScript)
 
 include(FindCygwin)
@@ -41,6 +42,7 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLINVENTORY_INCLUDE_DIRS}
+    ${LLPRIMITIVE_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
 
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 9cc2841e8c932387deb80f7b597869ddddf0ea3a..8c891b3e8ff911fe1f3b6d592b338ac247aee7d0 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -34,6 +34,7 @@ FS			(f|F)
 #include "llregionflags.h"
 #include "lscript_http.h"
 #include "llclickaction.h"
+#include "llmediaentry.h"
 
 void count();
 void line_comment();
@@ -233,7 +234,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
 "CHANGED_OWNER"			{ count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); }	
 "CHANGED_REGION"		{ count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); }	
 "CHANGED_TELEPORT"		{ count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); }	
-"CHANGED_REGION_START"		{ count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }	
+"CHANGED_REGION_START"	{ count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }	
+"CHANGED_MEDIA"		    { count(); yylval.ival = CHANGED_MEDIA; return(INTEGER_CONSTANT); }	
 
 "OBJECT_UNKNOWN_DETAIL"	{ count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); }
 "OBJECT_NAME"			{ count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); }
@@ -622,6 +624,45 @@ extern "C" { int yyerror(const char *fmt, ...); }
 "TOUCH_INVALID_VECTOR"	  { count(); return(TOUCH_INVALID_VECTOR); }
 "TOUCH_INVALID_TEXCOORD"  { count(); return(TOUCH_INVALID_TEXCOORD); }
 
+"PRIM_MEDIA_ALT_IMAGE_ENABLE"        { count(); yylval.ival = LLMediaEntry::ALT_IMAGE_ENABLE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CONTROLS"                { count(); yylval.ival = LLMediaEntry::CONTROLS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CURRENT_URL"             { count(); yylval.ival = LLMediaEntry::CURRENT_URL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_HOME_URL"                { count(); yylval.ival = LLMediaEntry::HOME_URL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_LOOP"               { count(); yylval.ival = LLMediaEntry::AUTO_LOOP_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_PLAY"               { count(); yylval.ival = LLMediaEntry::AUTO_PLAY_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_SCALE"              { count(); yylval.ival = LLMediaEntry::AUTO_SCALE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_AUTO_ZOOM"               { count(); yylval.ival = LLMediaEntry::AUTO_ZOOM_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_FIRST_CLICK_INTERACT"    { count(); yylval.ival = LLMediaEntry::FIRST_CLICK_INTERACT_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WIDTH_PIXELS"            { count(); yylval.ival = LLMediaEntry::WIDTH_PIXELS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_HEIGHT_PIXELS"           { count(); yylval.ival = LLMediaEntry::HEIGHT_PIXELS_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WHITELIST_ENABLE"        { count(); yylval.ival = LLMediaEntry::WHITELIST_ENABLE_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_WHITELIST"               { count(); yylval.ival = LLMediaEntry::WHITELIST_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERMS_INTERACT"          { count(); yylval.ival = LLMediaEntry::PERMS_INTERACT_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERMS_CONTROL"           { count(); yylval.ival = LLMediaEntry::PERMS_CONTROL_ID; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PARAM_MAX"               { count(); yylval.ival = LLMediaEntry::PARAM_MAX_ID; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_CONTROLS_STANDARD"       { count(); yylval.ival = LLMediaEntry::STANDARD; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_CONTROLS_MINI"           { count(); yylval.ival = LLMediaEntry::MINI; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_PERM_NONE"               { count(); yylval.ival = LLMediaEntry::PERM_NONE; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_OWNER"              { count(); yylval.ival = LLMediaEntry::PERM_OWNER; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_GROUP"              { count(); yylval.ival = LLMediaEntry::PERM_GROUP; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_PERM_ANYONE"             { count(); yylval.ival = LLMediaEntry::PERM_ANYONE; return(INTEGER_CONSTANT); }
+
+"PRIM_MEDIA_MAX_URL_LENGTH"          { count(); yylval.ival = LLMediaEntry::MAX_URL_LENGTH; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WHITELIST_SIZE"      { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_SIZE; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WHITELIST_COUNT"     { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_COUNT; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_WIDTH_PIXELS"        { count(); yylval.ival = LLMediaEntry::MAX_WIDTH_PIXELS; return(INTEGER_CONSTANT); }
+"PRIM_MEDIA_MAX_HEIGHT_PIXELS"       { count(); yylval.ival = LLMediaEntry::MAX_HEIGHT_PIXELS; return(INTEGER_CONSTANT); }
+
+"STATUS_OK"                          { count(); yylval.ival = LSL_STATUS_OK; return(INTEGER_CONSTANT); }
+"STATUS_MALFORMED_PARAMS"            { count(); yylval.ival = LSL_STATUS_MALFORMED_PARAMS; return(INTEGER_CONSTANT); }
+"STATUS_TYPE_MISMATCH"               { count(); yylval.ival = LSL_STATUS_TYPE_MISMATCH; return(INTEGER_CONSTANT); }
+"STATUS_BOUNDS_ERROR"                { count(); yylval.ival = LSL_STATUS_BOUNDS_ERROR; return(INTEGER_CONSTANT); }
+"STATUS_NOT_FOUND"                   { count(); yylval.ival = LSL_STATUS_NOT_FOUND; return(INTEGER_CONSTANT); }
+"STATUS_NOT_SUPPORTED"               { count(); yylval.ival = LSL_STATUS_NOT_SUPPORTED; return(INTEGER_CONSTANT); }
+"STATUS_INTERNAL_ERROR"              { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
+"STATUS_WHITELIST_FAILED"            { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
 
 {L}({L}|{N})*		{ count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }
 
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index 0d51c27c9227e1e2903b2f389936c9995b734e26..5e394644c2e686d43a16d8621aa17b2afea02533 100644
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
@@ -450,7 +450,12 @@ void LLScriptLibrary::init()
 	addFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis");
 	addFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks");
 
-	// energy, sleep, dummy_func, name, return type, parameters, gods-only
+	// Prim media (see lscript_prim_media.h)
+	addFunction(10.f, 1.0f, dummy_func, "llSetPrimMediaParams", "i", "il");
+	addFunction(10.f, 1.0f, dummy_func, "llGetPrimMediaParams", "l", "il");
+	addFunction(10.f, 1.0f, dummy_func, "llClearPrimMedia", "i", "i");
+
+	// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
 
 	// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
 	// Otherwise the bytecode numbers for each call will be wrong, and all
@@ -495,7 +500,7 @@ void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
 	        s << ", ";
 	}
 	switch (mType)
-	{
+    {
 	case LST_INTEGER:
 	     s << mInteger;
 	     break;
diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
index 647db7a5bfac2e63197d6690e34c9c8e261cd0f9..a4c43988baa8cc5a7277f00ec0a02baab7c21b46 100644
--- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
+++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
@@ -975,10 +975,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
 			else if(message_name == "shm_added")
 			{
 				SharedSegmentInfo info;
-				U64 address_lo = message_in.getValueU32("address");
-				U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
-				info.mAddress = (void*)((address_lo) |
-							(address_hi * (U64(1)<<31)));
+				info.mAddress = message_in.getValuePointer("address");
 				info.mSize = (size_t)message_in.getValueS32("size");
 				std::string name = message_in.getValue("name");
 
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index e9be45896061c2f1f8ba3f13761de82791b68a70..fbda65120d729708844453c2cc7bb967b349b424 100644
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -772,10 +772,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
 			else if(message_name == "shm_added")
 			{
 				SharedSegmentInfo info;
-				U64 address_lo = message_in.getValueU32("address");
-				U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
-				info.mAddress = (void*)((address_lo) |
-							(address_hi * (U64(1)<<31)));
+				info.mAddress = message_in.getValuePointer("address");
 				info.mSize = (size_t)message_in.getValueS32("size");
 				std::string name = message_in.getValue("name");
 
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index 2928b7e6b373ddd299bf48aa922ef38829554c1a..eb2457744ab5d67bd91832a421f26c7215274dcd 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -147,8 +147,11 @@ class MediaPluginWebKit :
 
 #if LL_WINDOWS
 			// Enable plugins
-			LLQtWebKit::getInstance()->enablePlugins(true);
-#else
+			LLQtWebKit::getInstance()->enablePlugins(false);
+#elif LL_DARWIN
+			// Disable plugins
+			LLQtWebKit::getInstance()->enablePlugins(false);
+#elif LL_LINUX
 			// Disable plugins
 			LLQtWebKit::getInstance()->enablePlugins(false);
 #endif
@@ -164,6 +167,11 @@ class MediaPluginWebKit :
 
 			// don't flip bitmap
 			LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
+			
+			// Set the background color to black
+			LLQtWebKit::getInstance()->
+			// set background color to be black - mostly for initial login page
+			LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 );
 
 			// go to the "home page"
 			// Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
@@ -483,8 +491,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 				mDepth = 4;
 
 				message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
-				message.setValueS32("default_width", 800);
-				message.setValueS32("default_height", 600);
+				message.setValueS32("default_width", 1024);
+				message.setValueS32("default_height", 1024);
 				message.setValueS32("depth", mDepth);
 				message.setValueU32("internalformat", GL_RGBA);
 				message.setValueU32("format", GL_RGBA);
@@ -507,10 +515,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 			else if(message_name == "shm_added")
 			{
 				SharedSegmentInfo info;
-				U64 address_lo = message_in.getValueU32("address");
-				U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
-				info.mAddress = (void*)((address_lo) |
-							(address_hi * (U64(1)<<31)));
+				info.mAddress = message_in.getValuePointer("address");
 				info.mSize = (size_t)message_in.getValueS32("size");
 				std::string name = message_in.getValue("name");
 				
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7b707a67203fc61374c2ea4c44e3e51d02d6065f..4482a754059d7a84e7ee92bbdfc95aba97b814dc 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -169,9 +169,9 @@ set(viewer_SOURCE_FILES
     llfloatergroups.cpp
     llfloaterhandler.cpp
     llfloaterhardwaresettings.cpp
-    llfloaterhtmlcurrency.cpp
+    llfloaterhelpbrowser.cpp
     llfloatermediabrowser.cpp
-    llfloaterhtmlsimple.cpp
+    llfloatermediasettings.cpp
     llfloaterhud.cpp
     llfloaterimagepreview.cpp
     llfloaterinspect.cpp
@@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES
     llfloaterurlentry.cpp
     llfloatervoicedevicesettings.cpp
     llfloaterwater.cpp
+    llfloaterwhitelistentry.cpp
     llfloaterwindlight.cpp
     llfloaterworldmap.cpp
     llfoldertype.cpp
@@ -260,6 +261,9 @@ set(viewer_SOURCE_FILES
     llmanipscale.cpp
     llmaniptranslate.cpp
     llmapresponders.cpp
+    llmediactrl.cpp
+    llmediadataresponder.cpp
+    llmediadatafetcher.cpp
     llmediaremotectrl.cpp
     llmemoryview.cpp
     llmenucommands.cpp
@@ -321,6 +325,9 @@ set(viewer_SOURCE_FILES
     llpanelmediahud.cpp
     llpanelmeprofile.cpp
     llpanelmovetip.cpp
+    llpanelmediasettingsgeneral.cpp
+    llpanelmediasettingssecurity.cpp
+    llpanelmediasettingspermissions.cpp
     llpanelobject.cpp
     llpanelpeople.cpp
     llpanelpeoplemenus.cpp
@@ -426,6 +433,8 @@ set(viewer_SOURCE_FILES
     llviewerfloaterreg.cpp
     llviewergenericmessage.cpp
     llviewergesture.cpp    
+    llviewerhelp.cpp
+    llviewerhelputil.cpp
     llviewerinventory.cpp
     llviewerjointattachment.cpp
     llviewerjoint.cpp
@@ -490,7 +499,6 @@ set(viewer_SOURCE_FILES
     llwearabledictionary.cpp
     llwearablelist.cpp
     llweb.cpp
-    llmediactrl.cpp
     llwind.cpp
     llwlanimator.cpp
     llwldaycycle.cpp
@@ -632,9 +640,9 @@ set(viewer_HEADER_FILES
     llfloatergroups.h
     llfloaterhandler.h
     llfloaterhardwaresettings.h
-    llfloaterhtmlcurrency.h
+    llfloaterhelpbrowser.h
     llfloatermediabrowser.h
-    llfloaterhtmlsimple.h
+    llfloatermediasettings.h
     llfloaterhud.h
     llfloaterimagepreview.h
     llfloaterinspect.h
@@ -671,6 +679,7 @@ set(viewer_HEADER_FILES
     llfloaterurlentry.h
     llfloatervoicedevicesettings.h
     llfloaterwater.h
+    llfloaterwhitelistentry.h
     llfloaterwindlight.h
     llfloaterworldmap.h
     llfoldertype.h
@@ -723,6 +732,8 @@ set(viewer_HEADER_FILES
     llmanipscale.h
     llmaniptranslate.h
     llmapresponders.h
+    llmediadataresponder.h
+    llmediadatafetcher.h
     llmediaremotectrl.h
     llmemoryview.h
     llmenucommands.h
@@ -781,6 +792,9 @@ set(viewer_HEADER_FILES
     llpanelmediahud.h
     llpanelmeprofile.h
     llpanelmovetip.h
+    llpanelmediasettingsgeneral.h
+    llpanelmediasettingssecurity.h
+    llpanelmediasettingspermissions.h
     llpanelobject.h
     llpanelpeople.h
     llpanelpeoplemenus.h
@@ -891,6 +905,7 @@ set(viewer_HEADER_FILES
     llviewerfloaterreg.h
     llviewergenericmessage.h
     llviewergesture.h    
+    llviewerhelp.h
     llviewerinventory.h
     llviewerjoint.h
     llviewerjointattachment.h
@@ -1526,6 +1541,7 @@ endif (INSTALL)
 include(LLAddBuildTest)
 SET(viewer_TEST_SOURCE_FILES
   llagentaccess.cpp
+  llviewerhelputil.cpp
   )
 set_source_files_properties(
   ${viewer_TEST_SOURCE_FILES}
@@ -1565,7 +1581,7 @@ if (WINDOWS)
         -E
         copy_if_different
         ${BUILT_SLPLUGIN}
-        ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
+        ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
       COMMENT "Copying SLPlugin executable to the runtime folder."
       )
 
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index eaf5213985dac4e861ac3aa62cc0bc9ebc791ada..5d521582988c80d1b2654933be0443a258f4c40d 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -40,14 +40,14 @@ not_at_rot_target	not_at_rot_target():Result of LLRotTarget library function cal
 money			money(key id, integer amount):Triggered when L$ is given to task
 email			email(string time, string address, string subj, string message, integer num_left):Triggered when task receives email
 run_time_permissions	run_time_permissions(integer perm):Triggered when an agent grants run time permissions to task
-attach			attach(key id):Triggered when an agent attaches or detaches from agent
+attach			attach(key id):Triggered when task attaches or detaches from agent
 dataserver      dataserver(key queryid, string data):Triggered when task receives asynchronous data
 moving_start	moving_start():Triggered when task begins moving
 moving_end		moving_end():Triggered when task stops moving
 on_rez			on_rez(integer start_param):Triggered when task is rezed in from inventory or another task
 object_rez		object_rez(key id):Triggered when task rezes in another task
 link_message	link_message(integer sender_num, integer num, string str, key id):Triggered when task receives a link message via LLMessageLinked library function call
-changed			changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT)
+changed			changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT, CHANGED_REGION_START, CHANGED_MEDIA)
 remote_data     remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY)
 http_response   http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
 http_request	http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
@@ -320,6 +320,7 @@ CHANGED_OWNER		Parameter of changed event handler used to indicate change to tas
 CHANGED_REGION		Parameter of changed event handler used to indicate the region has changed
 CHANGED_TELEPORT	Parameter of changed event handler used to indicate teleport has completed
 CHANGED_REGION_START	Parameter of changed event handler used to indicate the region has been restarted
+CHANGED_MEDIA       Parameter of changed event handler used to indicate that media has changed on a face of the task
 
 TYPE_INTEGER		Indicates that the list entry is holding an integer
 TYPE_FLOAT			Indicates that the list entry is holding an float
@@ -513,6 +514,46 @@ TOUCH_INVALID_TEXCOORD  Value returned by llDetectedTouchUV() and llDetectedTouc
 TOUCH_INVALID_VECTOR    Value returned by llDetectedTouchPos(), llDetectedTouchNormal(), and llDetectedTouchBinormal() when the touch position is not valid.
 TOUCH_INVALID_FACE      Value returned by llDetectedTouchFace() when the touch position is not valid.
 
+PRIM_MEDIA_ALT_IMAGE_ENABLE            Used with ll{Get,Set}PrimMediaParams to enable the default alt image for media 
+PRIM_MEDIA_CONTROLS                    Used with ll{Get,Set}PrimMediaParams to determine the controls shown for media
+PRIM_MEDIA_CURRENT_URL                 Used with ll{Get,Set}PrimMediaParams to navigate/access the current URL
+PRIM_MEDIA_HOME_URL                    Used with ll{Get,Set}PrimMediaParams to access the home URL
+PRIM_MEDIA_AUTO_LOOP                   Used with ll{Get,Set}PrimMediaParams to determine if media should auto-loop (if applicable)
+PRIM_MEDIA_AUTO_PLAY                   Used with ll{Get,Set}PrimMediaParams to determine if media should start playing as soon as it is created
+PRIM_MEDIA_AUTO_SCALE                  Used with ll{Get,Set}PrimMediaParams to determine if media should scale to fit the face it is on 
+PRIM_MEDIA_AUTO_ZOOM                   Used with ll{Get,Set}PrimMediaParams to determine if the user would zoom in when viewing media
+PRIM_MEDIA_FIRST_CLICK_INTERACT        Used with ll{Get,Set}PrimMediaParams to determine whether the user interacts with media or not when she first clicks it (versus selection)
+PRIM_MEDIA_WIDTH_PIXELS                Used with ll{Get,Set}PrimMediaParams to access the media's width in pixels
+PRIM_MEDIA_HEIGHT_PIXELS               Used with ll{Get,Set}PrimMediaParams to access the media's height in pixels
+PRIM_MEDIA_WHITELIST_ENABLE            Used with ll{Get,Set}PrimMediaParams to determine if the domain whitelist is enabled
+PRIM_MEDIA_WHITELIST                   Used with ll{Get,Set}PrimMediaParams to access the media's list of allowable URL prefixes to navigate to
+PRIM_MEDIA_PERMS_INTERACT              Used with ll{Get,Set}PrimMediaParams to determine the permissions for who can interact with the media
+PRIM_MEDIA_PERMS_CONTROL               Used with ll{Get,Set}PrimMediaParams to determine the permissions for who has controls
+PRIM_MEDIA_PARAM_MAX                   The value of the largest media param
+
+PRIM_MEDIA_CONTROLS_STANDARD           Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "standard controls"
+PRIM_MEDIA_CONTROLS_MINI               Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "mini controls"              
+
+PRIM_MEDIA_PERM_NONE                   Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, no permissions
+PRIM_MEDIA_PERM_OWNER                  Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, owner permissions
+PRIM_MEDIA_PERM_GROUP                  Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, group permissions
+PRIM_MEDIA_PERM_ANYONE                 Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, anyone has permissions
+
+PRIM_MEDIA_MAX_URL_LENGTH              Used with ll{Get,Set}PrimMediaParams, the maximum length of PRIM_MEDIA_CURRENT_URL or PRIM_MEDIA_HOME_URL
+PRIM_MEDIA_MAX_WHITELIST_SIZE          Used with ll{Get,Set}PrimMediaParams, the maximum length, in bytes, of PRIM_MEDIA_WHITELIST
+PRIM_MEDIA_MAX_WHITELIST_COUNT         Used with ll{Get,Set}PrimMediaParams, the maximum number of items allowed in PRIM_MEDIA_WHITELIST
+PRIM_MEDIA_MAX_WIDTH_PIXELS            Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_WIDTH_PIXELS
+PRIM_MEDIA_MAX_HEIGHT_PIXELS           Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_HEIGHT_PIXELS
+
+STATUS_OK                              Result of function call was success
+STATUS_MALFORMED_PARAMS                Function was called with malformed params
+STATUS_TYPE_MISMATCH                   Argument(s) passed to function had a type mismatch
+STATUS_BOUNDS_ERROR                    Argument(s) passed to function had a bounds error 
+STATUS_NOT_FOUND                       Object or other item was not found
+STATUS_NOT_SUPPORTED                   Feature not supported
+STATUS_INTERNAL_ERROR                  An internal error occurred
+STATUS_WHITELIST_FAILED                URL failed to pass whitelist
+
 # string constants
 [word .1, .3, .5]
 NULL_KEY			Indicates an empty key
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 19d503390c60313bf4d6f6a8b899052b5f72885d..99b662a63f3777b3dce5db221daf9768709ee600 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3542,28 +3542,28 @@
       <string>S32</string>
       <key>Value</key>
       <integer>400</integer>
-    </map>  
-    <key>HelpHomeURL</key>
+    </map>
+    <key>HelpUseLocal</key>
     <map>
       <key>Comment</key>
-      <string>URL of initial help page</string>
+      <string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string>
       <key>Persist</key>
-      <integer>1</integer>
+      <integer>0</integer>
       <key>Type</key>
-      <string>String</string>
+      <string>Boolean</string>
       <key>Value</key>
-      <string>help/index.html</string>
+      <integer>0</integer>
     </map>
-    <key>HelpLastVisitedURL</key>
+    <key>HelpURLFormat</key>
     <map>
       <key>Comment</key>
-      <string>URL of last help page, will be shown next time help is accessed</string>
+      <string>URL pattern for help page; arguments will be encoded; see llviewerhelp.cpp:buildHelpURL for arguments</string>
       <key>Persist</key>
-      <integer>1</integer>
+      <integer>0</integer>
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>help/index.html</string>
+      <string>http://www.google.com/search?q=site%3Awiki.secondlife.com+[TOPIC]&amp;ignore_channel=[CHANNEL]&amp;ignore_version=[VERSION]&amp;ignore_os=[OS]&amp;ignore_language=[LANGUAGE]&amp;ignore_version_major=[VERSION_MAJOR]&amp;ignore_version_minor=[VERSION_MINOR]&amp;ignore_version_patch=[VERSION_PATCH]&amp;ignore_version_build=[VERSION_BUILD]</string>
     </map>
     <key>HighResSnapshot</key>
     <map>
@@ -3994,6 +3994,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LastMediaSettingsTab</key>
+    <map>
+      <key>Comment</key>
+      <string>Last selected tab in media settings window</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LastRunVersion</key>
     <map>
       <key>Comment</key>
@@ -4455,7 +4466,7 @@
     <key>Type</key>
     <string>Boolean</string>
     <key>Value</key>
-    <integer>0</integer>
+    <integer>1</integer>
   </map>
   <key>MemoryLogFrequency</key>
         <map>
@@ -5216,6 +5227,51 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+
+    <key>PluginInstancesCPULimit</key>
+    <map>
+      <key>Comment</key>
+      <string>Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority.  Set to 0 to disable this check.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>0.0</real>
+    </map>
+    <key>PluginInstancesLow</key>
+    <map>
+      <key>Comment</key>
+      <string>Limit on the number of inworld media plugins that will run at "low" priority</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>4</integer>
+    </map>
+    <key>PluginInstancesNormal</key>
+    <map>
+      <key>Comment</key>
+      <string>Limit on the number of inworld media plugins that will run at "normal" priority</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>4</integer>
+    </map>
+    <key>PluginInstancesTotal</key>
+    <map>
+      <key>Comment</key>
+      <string>Hard limit on the number of plugins that will be instantiated at once</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>16</integer>
+    </map>
     <key>PrecachingDelay</key>
     <map>
       <key>Comment</key>
@@ -5238,6 +5294,28 @@
       <key>Value</key>
 	  <integer>13</integer>
     </map>
+    <key>PrimMediaFetchQueueDelay</key>
+    <map>
+      <key>Comment</key>
+      <string>Timer delay for fetching media from the queue (in seconds).</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.0</real>
+    </map>
+    <key>PrimMediaRetryTimerDelay</key>
+    <map>
+      <key>Comment</key>
+      <string>Timer delay for retrying on media queries (in seconds).</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>5.0</real>
+    </map>
     <key>ProbeHardwareOnStartup</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 355660faa5add252db2a7aeca3f3eb0eea1cb6d5..30e0a5770c30c2e9c2d88b5c4ffd34b7f892cae8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -67,6 +67,7 @@
 #include "llviewerobjectlist.h"
 #include "llworldmap.h"
 #include "llmutelist.h"
+#include "llviewerhelp.h"
 #include "lluicolortable.h"
 #include "llurldispatcher.h"
 #include "llurlhistory.h"
@@ -663,8 +664,6 @@ bool LLAppViewer::init()
 	mNumSessions++;
 	gSavedSettings.setS32("NumSessions", mNumSessions);
 
-	gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
-
 	if (gSavedSettings.getBOOL("VerboseLogs"))
 	{
 		LLError::setPrintLocation(true);
@@ -694,6 +693,9 @@ bool LLAppViewer::init()
 	LLUrlAction::setOpenURLExternalCallback(&LLWeb::loadURLExternal);
 	LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
 
+	// Let code in llui access the viewer help floater
+	LLUI::sHelpImpl = LLViewerHelp::getInstance();
+
 	// Set the link color for any Urls in text fields
 	LLTextBase::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") );
 
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ee14a2ff865deef8683e5d5eb292d19515404c8f..36f9780ad0b18e2c03ef90357fb57ee99a42d4f2 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,10 @@
 
 static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
 
+// Maximum number of avatars that can be added to a list in one pass.
+// Used to limit time spent for avatar list update per frame.
+static const unsigned ADD_LIMIT = 50;
+
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
 {
     LLStringUtil::toUpper(haystack);
@@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
 :	LLFlatListView(p)
 , mOnlineGoFirst(p.online_go_first)
 , mContextMenu(NULL)
+, mDirty(true) // to force initial update
 {
 	setCommitOnSelectionChange(true);
 
@@ -72,44 +77,40 @@ LLAvatarList::LLAvatarList(const Params& p)
 	setComparator(&NAME_COMPARATOR);
 }
 
-void LLAvatarList::computeDifference(
-	const std::vector<LLUUID>& vnew_unsorted,
-	std::vector<LLUUID>& vadded,
-	std::vector<LLUUID>& vremoved)
+// virtual
+void LLAvatarList::draw()
 {
-	std::vector<LLUUID> vcur;
-	std::vector<LLUUID> vnew = vnew_unsorted;
+	if (mDirty)
+		refresh();
 
-	// Convert LLSDs to LLUUIDs.
-	{
-		std::vector<LLSD> vcur_values;
-		getValues(vcur_values);
+	LLFlatListView::draw();
+}
 
-		for (size_t i=0; i<vcur_values.size(); i++)
-			vcur.push_back(vcur_values[i].asUUID());
+void LLAvatarList::setNameFilter(const std::string& filter)
+{
+	if (mNameFilter != filter)
+	{
+		mNameFilter = filter;
+		setDirty();
 	}
+}
 
-	std::sort(vcur.begin(), vcur.end());
-	std::sort(vnew.begin(), vnew.end());
-
-	std::vector<LLUUID>::iterator it;
-	size_t maxsize = llmax(vcur.size(), vnew.size());
-	vadded.resize(maxsize);
-	vremoved.resize(maxsize);
-
-	// what to remove
-	it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
-	vremoved.erase(it, vremoved.end());
-
-	// what to add
-	it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
-	vadded.erase(it, vadded.end());
+void LLAvatarList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
 }
 
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+void LLAvatarList::refresh()
 {
-	BOOL have_names = TRUE;
-	bool have_filter = name_filter != LLStringUtil::null;
+	bool have_names			= TRUE;
+	bool add_limit_exceeded	= false;
+	bool modified			= false;
+	bool have_filter		= !mNameFilter.empty();
 
 	// Save selection.	
 	std::vector<LLUUID> selected_ids;
@@ -118,22 +119,36 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 
 	// Determine what to add and what to remove.
 	std::vector<LLUUID> added, removed;
-	LLAvatarList::computeDifference(all_buddies, added, removed);
+	LLAvatarList::computeDifference(getIDs(), added, removed);
 
 	// Handle added items.
+	unsigned nadded = 0;
 	for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
 	{
 		std::string name;
 		const LLUUID& buddy_id = *it;
-		have_names &= gCacheName->getFullName(buddy_id, name);
-		if (!have_filter || findInsensitive(name, name_filter))
-		addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+		have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+		if (!have_filter || findInsensitive(name, mNameFilter))
+		{
+			if (nadded >= ADD_LIMIT)
+			{
+				add_limit_exceeded = true;
+				break;
+			}
+			else
+			{
+				addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				modified = true;
+				nadded++;
+			}
+		}
 	}
 
 	// Handle removed items.
 	for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
 	{
 		removeItemByUUID(*it);
+		modified = true;
 	}
 
 	// Handle filter.
@@ -146,9 +161,12 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 		{
 			std::string name;
 			const LLUUID& buddy_id = it->asUUID();
-			have_names &= gCacheName->getFullName(buddy_id, name);
-			if (!findInsensitive(name, name_filter))
+			have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+			if (!findInsensitive(name, mNameFilter))
+			{
 				removeItemByUUID(buddy_id);
+				modified = true;
+			}
 		}
 	}
 
@@ -167,18 +185,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 	//
 	// Otherwise, if we have no filter then no need to update again
 	// because the items will update their names.
-	return !have_filter || have_names;
-}
+	bool dirty = add_limit_exceeded || (have_filter && !have_names);
+	setDirty(dirty);
 
-void LLAvatarList::sortByName()
-{
-	setComparator(&NAME_COMPARATOR);
-	sort();
+	// Commit if we've added/removed items.
+	if (modified)
+		onCommit();
 }
 
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+
 void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
 {
 	LLAvatarListItem* item = new LLAvatarListItem();
@@ -194,8 +209,39 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
 	addItem(item, id, pos);
 }
 
+void LLAvatarList::computeDifference(
+	const std::vector<LLUUID>& vnew_unsorted,
+	std::vector<LLUUID>& vadded,
+	std::vector<LLUUID>& vremoved)
+{
+	std::vector<LLUUID> vcur;
+	std::vector<LLUUID> vnew = vnew_unsorted;
 
+	// Convert LLSDs to LLUUIDs.
+	{
+		std::vector<LLSD> vcur_values;
+		getValues(vcur_values);
 
+		for (size_t i=0; i<vcur_values.size(); i++)
+			vcur.push_back(vcur_values[i].asUUID());
+	}
+
+	std::sort(vcur.begin(), vcur.end());
+	std::sort(vnew.begin(), vnew.end());
+
+	std::vector<LLUUID>::iterator it;
+	size_t maxsize = llmax(vcur.size(), vnew.size());
+	vadded.resize(maxsize);
+	vremoved.resize(maxsize);
+
+	// what to remove
+	it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+	vremoved.erase(it, vremoved.end());
+
+	// what to add
+	it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+	vadded.erase(it, vadded.end());
+}
 
 bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
 {
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8d79e073d2c5da9193b51f7e50e2873d7f8bfabb..ec801645feb10c1e229d1cc6359bc41d89aa3061 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -37,10 +37,22 @@
 
 #include "llavatarlistitem.h"
 
+/**
+ * Generic list of avatars.
+ * 
+ * Updates itself when it's dirty, using optional name filter.
+ * To initiate update, modify the UUID list and call setDirty().
+ * 
+ * @see getIDs()
+ * @see setDirty()
+ * @see setNameFilter()
+ */
 class LLAvatarList : public LLFlatListView
 {
 	LOG_CLASS(LLAvatarList);
 public:
+	typedef std::vector<LLUUID> uuid_vector_t;
+
 	struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> 
 	{
 		Optional<S32> volume_column_width;
@@ -51,14 +63,19 @@ class LLAvatarList : public LLFlatListView
 	LLAvatarList(const Params&);
 	virtual	~LLAvatarList() {}
 
-	BOOL update(const std::vector<LLUUID>& all_buddies,
-		const std::string& name_filter = LLStringUtil::null);
+	virtual void draw(); // from LLView
+
+	void setNameFilter(const std::string& filter);
+	void setDirty(bool val = true)						{ mDirty = val; }
+	uuid_vector_t& getIDs() 							{ return mIDs; }
 
 	void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
 
 	void sortByName();
 
 protected:
+	void refresh();
+
 	void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
 	void computeDifference(
 		const std::vector<LLUUID>& vnew,
@@ -68,6 +85,10 @@ class LLAvatarList : public LLFlatListView
 private:
 
 	bool mOnlineGoFirst;
+	bool mDirty;
+
+	std::string				mNameFilter;
+	uuid_vector_t			mIDs;
 
 	LLAvatarListItem::ContextMenu* mContextMenu;
 };
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 46151b469f26e2b933300c98d865a2cc2e8a28ad..8771611b1c5a3d04caa9873f9c51a481dc6e6db8 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
 	case LLIMChiclet::TYPE_IM:
 		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
 	case LLIMChiclet::TYPE_GROUP:
+	case LLIMChiclet::TYPE_AD_HOC:
 		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
 	case LLIMChiclet::TYPE_UNKNOWN:
 		break;
@@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
 			mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
 			LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
 		
-		}
+	}
 }
 
 void LLBottomTray::showGestureButton(BOOL visible)
@@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
 		mGestureCombo->setVisible(visible);
 
 		if (!visible)
-	{
+		{
 			LLFloaterReg::hideFloaterInstance("gestures");
 			r.mRight -= mGestureCombo->getRect().getWidth();
 		}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 7ae99763382e8f8c33655180e45f669f6dec08e1..c4619dc57a50ba0997ac30fb74e65c633235b968 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
 	p.channel_align = CA_RIGHT;
 
 	// Getting a Channel for our notifications
-	return LLChannelManager::getInstance()->getChannel(p);
+	return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
 }
 
 //--------------------------------------------------------------------------
@@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
 	LLChannelManager::Params p;
 	p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
 	p.channel_align = CA_RIGHT;
-	mStartUpChannel = getChannel(p);
+	mStartUpChannel = createChannel(p);
 
 	if(!mStartUpChannel)
 	{
@@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
 	LLScreenChannel::setStartUpToastShown();
 
 	// force NEARBY CHAT CHANNEL to repost all toasts if present
-	LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
-	nearby_channel->loadStoredToastsToChannel();
-	nearby_channel->setCanStoreToasts(false);
+	//LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	//!!!!!!!!!!!!!!
+	//FIXME
+	//nearby_channel->loadStoredToastsToChannel();
+	//nearby_channel->setCanStoreToasts(false);
 }
 
 //--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
+
+LLScreenChannelBase*	LLChannelManager::addChannel(LLScreenChannelBase* channel)
 {
-	LLScreenChannel* new_channel = NULL;
+	if(!channel)
+		return 0;
 
-	new_channel = findChannelByID(p.id);
+	ChannelElem new_elem;
+	new_elem.id = channel->getChannelID();
+	new_elem.channel = channel;
 
-	if(new_channel)
-		return new_channel;
+	mChannelList.push_back(new_elem); 
 
-	new_channel = new LLScreenChannel(p.id); 
+	return channel;
+}
+
+LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
+{
+	LLScreenChannel* new_channel = new LLScreenChannel(p.id); 
 
 	if(!new_channel)
 	{
@@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
 	{
 		new_channel->setToastAlignment(p.toast_align);
 		new_channel->setChannelAlignment(p.channel_align);
-	new_channel->setDisplayToastsAlways(p.display_toasts_always);
-
-	ChannelElem new_elem;
-	new_elem.id = p.id;
-	new_elem.channel = new_channel;
+		new_channel->setDisplayToastsAlways(p.display_toasts_always);
 
-		mChannelList.push_back(new_elem); 
+		addChannel(new_channel);
 	}
-
 	return new_channel;
 }
 
+LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
+{
+	LLScreenChannelBase* new_channel = findChannelByID(p.id);
+
+	if(new_channel)
+		return new_channel;
+
+	return createChannel(p);
+
+}
+
 //--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
+LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
 {
 	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id); 
 	if(it != mChannelList.end())
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 811fa06d2b4f4c36ba164d921b7ae9df6fe1a257..b927d369cd4b6d17cfd5339d3c1371c53e59ac4f 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 public:	
 	struct Params
 	{
-		LLUUID			id;
-		bool			display_toasts_always;
+		LLUUID				id;
+		bool				display_toasts_always;
 		EToastAlignment		toast_align;
 		EChannelAlignment	channel_align;
 
@@ -64,7 +64,7 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 	struct ChannelElem
 	{
 		LLUUID				id;
-		LLScreenChannel*	channel;
+		LLScreenChannelBase*	channel;
 
 		ChannelElem() : id(LLUUID("")), channel(NULL) { }
 
@@ -89,19 +89,23 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 	void onStartUpToastClose();
 
 	// creates a new ScreenChannel according to the given parameters or returns existing if present
-	LLScreenChannel*	getChannel(LLChannelManager::Params& p);
+	LLScreenChannelBase*	getChannel(LLChannelManager::Params& p);
+
+	LLScreenChannelBase*	addChannel(LLScreenChannelBase* channel);
 
 	// returns a channel by its ID
-	LLScreenChannel*	findChannelByID(const LLUUID id);
+	LLScreenChannelBase*	findChannelByID(const LLUUID id);
 
 	// creator of the Notification channel, that is used in more than one handler
-	LLScreenChannel*	createNotificationChannel();
+	LLScreenChannel*		createNotificationChannel();
 
 	// remove channel methods
 	void	removeChannelByID(const LLUUID id);
 
 private:
 
+	LLScreenChannel* createChannel(LLChannelManager::Params& p);
+
 	LLScreenChannel*			mStartUpChannel;
 	std::vector<ChannelElem>	mChannelList;
 };
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 96c707b08f25bb808b774a39a414842729989410..4523267eddbaa6342b2af0365850f0d82d2f1b91 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -125,8 +125,8 @@ BOOL LLChatBar::postBuild()
 
 	mInputEditor = getChild<LLLineEditor>("Chat Editor");
 	mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
-	mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
-	mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
+	mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost));
+	mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus));
 	mInputEditor->setCommitOnFocusLost( FALSE );
 	mInputEditor->setRevertOnEsc( FALSE );
 	mInputEditor->setIgnoreTab(TRUE);
@@ -538,14 +538,14 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
 }
 
 // static
-void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
+void LLChatBar::onInputEditorFocusLost()
 {
 	// stop typing animation
 	gAgent.stopTyping();
 }
 
 // static
-void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
+void LLChatBar::onInputEditorGainFocus()
 {
 	LLFloaterChat::setHistoryCursorAndScrollToEnd();
 }
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
index a41947218de08d96e18e67176e892618257c3f83..86aa3ebd2a957cdff66dacd44f6499dc7a43411e 100644
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
@@ -87,8 +87,8 @@ class LLChatBar
 
 	static void	onTabClick( void* userdata );
 	static void	onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
-	static void	onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
-	static void	onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
+	static void	onInputEditorFocusLost();
+	static void	onInputEditorGainFocus();
 
 	void onCommitGesture(LLUICtrl* ctrl);
 
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 6fb6552f2db0f8b143fd5e8427bf51866479a8e3..c2d7e0d9359c6372c5619ca54d8a46cdd5f1c4be 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -44,6 +44,7 @@
 #include "llviewercontrol.h"
 #include "llagentdata.h"
 
+/*
 static const S32 BORDER_MARGIN = 2;
 static const S32 PARENT_BORDER_MARGIN = 0;
 
@@ -53,33 +54,27 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
 static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
 static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
 
-static const S32 msg_left_offset = 30;
-static const S32 msg_right_offset = 10;
-
 #define MAX_CHAT_HISTORY 100
+*/
 
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
 
-static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl>	t2("chat_items_container");
-
-
+//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl>	t2("chat_items_container");
 
 //*******************************************************************************************************************
 //LLChatItemCtrl
 //*******************************************************************************************************************
 
-LLChatItemCtrl* LLChatItemCtrl::createInstance()
+LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
 {
-	LLChatItemCtrl* item = new LLChatItemCtrl();
+	LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
 	LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
+	item->setFollows(FOLLOWS_NONE);
 	return item;
 }
 
-void	LLChatItemCtrl::draw()
-{
-	LLPanel::draw();
-}
-
-void	LLChatItemCtrl::reshape		(S32 width, S32 height, BOOL called_from_parent )
+void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
 {
 	LLPanel::reshape(width, height,called_from_parent);
 
@@ -101,13 +96,13 @@ void	LLChatItemCtrl::reshape		(S32 width, S32 height, BOOL called_from_parent )
 	}
 }
 
-BOOL LLChatItemCtrl::postBuild()
+BOOL LLNearbyChatToastPanel::postBuild()
 {
 	return LLPanel::postBuild();
 }
 
 
-std::string LLChatItemCtrl::appendTime()
+std::string LLNearbyChatToastPanel::appendTime()
 {
 	time_t utc_time;
 	utc_time = time_corrected();
@@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
 
 
 
-void	LLChatItemCtrl::addText		(const std::string& message)
+void	LLNearbyChatToastPanel::addText		(const std::string& message)
 {
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
 	msg_text->addText(message);
 	mMessages.push_back(message);
 }
 
-void	LLChatItemCtrl::setMessage	(const LLChat& msg)
+void LLNearbyChatToastPanel::init(LLSD& notification)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 
+	mText = notification["message"].asString();		// UTF-8 line of text
+	mFromName = notification["from"].asString();	// agent or object name
+	mFromID = notification["from_id"].asUUID();		// agent id or object id
+	int sType = notification["source"].asInteger();
+    mSourceType = (EChatSourceType)sType;
+
 	std::string str_sender;
 
-	
-	if(gAgentID != msg.mFromID)
-		str_sender = msg.mFromName;
+	if(gAgentID != mFromID)
+		str_sender = mFromName;
 	else
 		str_sender = LLTrans::getString("You");;
 
 	caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
 	
-	std::string tt = appendTime();
-	
-	caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
-
-
-	caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
+	caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
 
-	mOriginalMessage = msg;
 
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
-	msg_text->setText(msg.mText);
+	msg_text->setText(mText);
 
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		msg_inspector->setVisible(false);
 
 	mMessages.clear();
 
+	snapToMessageHeight	();
+
+	mIsDirty = true;//will set Avatar Icon in draw
+}
+
+void	LLNearbyChatToastPanel::setMessage	(const LLChat& chat_msg)
+{
+	LLSD notification;
+	notification["message"] = chat_msg.mText;
+	notification["from"] = chat_msg.mFromName;
+	notification["from_id"] = chat_msg.mFromID;
+	notification["time"] = chat_msg.mTime;
+	notification["source"] = (S32)chat_msg.mSourceType;
+
+	init(notification);
+
 }
 
-void	LLChatItemCtrl::snapToMessageHeight	()
+void	LLNearbyChatToastPanel::snapToMessageHeight	()
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	S32 new_height = text_box->getTextPixelHeight();
@@ -184,14 +194,14 @@ void	LLChatItemCtrl::snapToMessageHeight	()
 }
 
 
-void	LLChatItemCtrl::setWidth(S32 width)
+void	LLNearbyChatToastPanel::setWidth(S32 width)
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
 
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
-	if(mOriginalMessage.mText.length())
-		msg_text->setText(mOriginalMessage.mText);
+	if(mText.length())
+		msg_text->setText(mText);
 	
 	for(size_t i=0;i<mMessages.size();++i)
 		msg_text->addText(mMessages[i]);
@@ -200,25 +210,25 @@ void	LLChatItemCtrl::setWidth(S32 width)
 	snapToMessageHeight	();
 }
 
-void LLChatItemCtrl::onMouseLeave			(S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
 	msg_inspector->setVisible(false);
 	
 }
-void LLChatItemCtrl::onMouseEnter				(S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
 {
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		return;
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
 	msg_inspector->setVisible(true);
 }
 
-BOOL	LLChatItemCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
+BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
 {
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		return LLPanel::handleMouseDown(x,y,mask);
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
@@ -226,12 +236,16 @@ BOOL	LLChatItemCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
 	S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
 	if(msg_inspector->pointInView(local_x, local_y))
 	{
-		LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
+		LLFloaterReg::showInstance("inspect_avatar", mFromID);
+	}
+	else
+	{
+		LLFloaterReg::showInstance("nearby_chat",LLSD());
 	}
 	return LLPanel::handleMouseDown(x,y,mask);
 }
 
-void	LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
+void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 
@@ -243,7 +257,7 @@ void	LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
 
 }
 
-bool	LLChatItemCtrl::canAddText	()
+bool	LLNearbyChatToastPanel::canAddText	()
 {
 	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
 	if(!msg_text)
@@ -251,7 +265,7 @@ bool	LLChatItemCtrl::canAddText	()
 	return msg_text->getTextLinesNum()<10;
 }
 
-BOOL	LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
@@ -260,296 +274,20 @@ BOOL	LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
 
 	//eat message for avatar icon if msg was from object
-	if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
 		return TRUE;
 	return LLPanel::handleRightMouseDown(x,y,mask);
 }
-
-
-//*******************************************************************************************************************
-//LLChatItemsContainerCtrl
-//*******************************************************************************************************************
-
-LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
-{
-	mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
-}
-
-
-void	LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
-{
-	/*
-	if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
-		return;
-	*/
-	if(mItems.size() >= MAX_CHAT_HISTORY)
-	{
-		LLChatItemCtrl* item = mItems[0];
-		removeChild(item);
-		delete item;
-		mItems.erase(mItems.begin());
-	}
-
-	
-	if(mItems.size() > 0 
-		&& msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID 
-		&& (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
-		&& mItems[mItems.size()-1]->canAddText()
-		)
-	{
-		mItems[mItems.size()-1]->addText(msg.mText);
-		mItems[mItems.size()-1]->snapToMessageHeight();
-	}
-	else
-	{
-		LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-		mItems.push_back(item);
-		addChild(item,0);
-		item->setWidth(getRect().getWidth() - 16);
-		item->setMessage(msg);
-		item->snapToMessageHeight();
-		
-		item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
-
-		item->setVisible(true);
-	}
-
-	arrange(getRect().getWidth(),getRect().getHeight());
-	updateLayout(getRect().getWidth(),getRect().getHeight());
-	scrollToBottom();
-}
-
-void	LLChatItemsContainerCtrl::scrollToBottom	()
-{
-	if(mScrollbar->getVisible())
-	{
-		mScrollbar->setDocPos(mScrollbar->getDocPosMax());
-		onScrollPosChangeCallback(0,0);
-	}
-}
-
-void	LLChatItemsContainerCtrl::draw()
-{
-	LLLocalClipRect clip(getRect());
-	LLPanel::draw();
-}
-
-void	LLChatItemsContainerCtrl::reshape					(S32 width, S32 height, BOOL called_from_parent )
-{
-	S32 delta_width = width - getRect().getWidth();
-	S32 delta_height = height - getRect().getHeight();
-
-	if (delta_width || delta_height || sForceReshape)
-	{
-		arrange(width, height);
-	}
-
-	updateBoundingRect();
-}
-
-void	LLChatItemsContainerCtrl::arrange					(S32 width, S32 height)
+void LLNearbyChatToastPanel::draw()
 {
-	S32 delta_width = width - getRect().getWidth();
-	if(delta_width)//width changed...too bad. now we need to reformat all items
-		reformatHistoryScrollItems(width);
-
-	calcRecuiredHeight();
-
-	show_hide_scrollbar(width,height);
-
-	updateLayout(width,height);
-}
-
-void	LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
-{
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
-	{
-		(*it)->setWidth(width);
-	}
-}
-
-S32		LLChatItemsContainerCtrl::calcRecuiredHeight	()
-{
-	S32 rec_height = 0;
-	
-	std::vector<LLChatItemCtrl*>::iterator it;
-	for(it=mItems.begin(); it!=mItems.end(); ++it)
-	{
-		rec_height += (*it)->getRect().getHeight();
-	}
-
-	mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
-
-	return mInnerRect.getHeight();
-}
-
-
-void	LLChatItemsContainerCtrl::updateLayout				(S32 width, S32 height)
-{
-	S32 panel_top = height - BORDER_MARGIN ;
-	S32 panel_width = width;
-	if(mScrollbar->getVisible())
-	{
-		static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-		
-		panel_top+=mScrollbar->getDocPos();
-		panel_width-=scrollbar_size;
-	}
-
-
-	//set sizes for first panels and dragbars
-	for(size_t i=0;i<mItems.size();++i)
-	{
-		LLRect panel_rect = mItems[i]->getRect();
-		panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
-		panel_top-=panel_rect.getHeight();
-	}
-}
-
-void	LLChatItemsContainerCtrl::show_hide_scrollbar		(S32 width, S32 height)
-{
-	calcRecuiredHeight();
-	if(getRecuiredHeight() > height )
-		showScrollbar(width, height);
-	else
-		hideScrollbar(width, height);
-}
-
-void	LLChatItemsContainerCtrl::showScrollbar			(S32 width, S32 height)
-{
-	bool was_visible = mScrollbar->getVisible();
-
-	mScrollbar->setVisible(true);
-
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-	
-	panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
-		,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
-	
-	mScrollbar->setPageSize(height);
-	mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
-
-	if(was_visible)
-	{
-		S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
-		mScrollbar->setDocPos(scroll_pos);
-		updateLayout(width,height);
-		return;
-	}
-}
-
-void	LLChatItemsContainerCtrl::hideScrollbar			(S32 width, S32 height)
-{
-	if(mScrollbar->getVisible() == false)
-		return;
-	mScrollbar->setVisible(false);
-
-	mScrollbar->setDocPos(0);
-
-	if(mItems.size()>0)
-	{
-		S32 panel_top = height - BORDER_MARGIN;		  // Top coordinate of the first panel
-		S32 diff = panel_top - mItems[0]->getRect().mTop;
-		shiftPanels(diff);
-	}
-}
-
-//---------------------------------------------------------------------------------
-void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
-{
-	if(!panel)
-		return;
-	LLRect panel_rect = panel->getRect();
-	panel_rect.setLeftTopAndSize( left, top, width, height);
-	panel->reshape( width, height, 1);
-	panel->setRect(panel_rect);
-}
-
-void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
-{
-	if(!panel)
-		return;
-	panel->translate(0,delta);
-}
-
-void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
-{
-	//Arrange panels
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
-	{
-		panelShiftVertical((*it),delta);
-	}	
-
-}
-
-//---------------------------------------------------------------------------------
-
-void	LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
-{
-	updateLayout(getRect().getWidth(),getRect().getHeight());
-}
-
-BOOL LLChatItemsContainerCtrl::postBuild()
-{
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
-	LLRect scroll_rect;
-	scroll_rect.setOriginAndSize( 
-		getRect().getWidth() - scrollbar_size,
-		1,
-		scrollbar_size,
-		getRect().getHeight() - 1);
-	
-
-	LLScrollbar::Params sbparams;
-	sbparams.name("scrollable vertical");
-	sbparams.rect(scroll_rect);
-	sbparams.orientation(LLScrollbar::VERTICAL);
-	sbparams.doc_size(mInnerRect.getHeight());
-	sbparams.doc_pos(0);
-	sbparams.page_size(mInnerRect.getHeight());
-	sbparams.step_size(VERTICAL_MULTIPLE);
-	sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
-	sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
-	
-	mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
-	LLView::addChild( mScrollbar );
-	mScrollbar->setVisible( true );
-	mScrollbar->setFollowsRight();
-	mScrollbar->setFollowsTop();
-	mScrollbar->setFollowsBottom();
-
-	reformatHistoryScrollItems(getRect().getWidth());
-	arrange(getRect().getWidth(),getRect().getHeight());
-
-	return LLPanel::postBuild();
-}
-BOOL	LLChatItemsContainerCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
-{
-	return LLPanel::handleMouseDown(x,y,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleKeyHere			(KEY key, MASK mask)
-{
-	if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
-		return TRUE;
-	return LLPanel::handleKeyHere(key,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleScrollWheel		( S32 x, S32 y, S32 clicks )
-{
-	if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
-		return TRUE;
-	return false;
-}
-
-void	LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
-{
-	if(e == mEShowItemHeader)
-		return;
-	mEShowItemHeader = e;
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+	if(mIsDirty)
 	{
-		(*it)->setHeaderVisibility(e);
+		LLPanel* caption = findChild<LLPanel>("msg_caption", false);
+		if(caption)
+			caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
+		mIsDirty = false;
 	}
+	LLToastPanelBase::draw();
 }
 
 
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index de16cf9505c233a2abbcd757aa20cd5e524823cc..8fb045b6d912f7bac2c2eeba3513093219730977 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -37,6 +37,7 @@
 #include "llscrollbar.h"
 #include "string"
 #include "llchat.h"
+#include "lltoastpanel.h"
 
 typedef enum e_show_item_header
 {
@@ -45,20 +46,18 @@ typedef enum e_show_item_header
 	CHATITEMHEADER_SHOW_BOTH
 } EShowItemHeader;
 
-class LLChatItemCtrl: public LLPanel
+class LLNearbyChatToastPanel: public LLToastPanelBase
 {
 protected:
-	LLChatItemCtrl(){};
+	LLNearbyChatToastPanel():mIsDirty(false){};
 public:
 	
 
-	~LLChatItemCtrl(){}
+	~LLNearbyChatToastPanel(){}
 	
-	static LLChatItemCtrl* createInstance();
+	static LLNearbyChatToastPanel* createInstance();
 
-	void	draw();
-
-	const LLChat& getMessage() const { return mOriginalMessage;}
+	const LLUUID& getFromID() const { return mFromID;}
 	
 	void	addText		(const std::string& message);
 	void	setMessage	(const LLChat& msg);
@@ -77,78 +76,27 @@ class LLChatItemCtrl: public LLPanel
 
 	void	setHeaderVisibility(EShowItemHeader e);
 	BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
-private:
-	
-	std::string appendTime	();
-
-private:
-	LLChat mOriginalMessage;
-
-	std::vector<std::string> mMessages;
-};
-
-class LLChatItemsContainerCtrl: public LLPanel
-{
-public:
-	struct Params 
-	:	public LLInitParam::Block<Params, LLPanel::Params>
-	{
-		Params(){};
-	};
-
-	LLChatItemsContainerCtrl(const Params& params);
-
-
-	~LLChatItemsContainerCtrl(){}
-
-	void	addMessage	(const LLChat& msg);
-
-	void	draw();
-
-	void	reshape					(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
-	void	onScrollPosChangeCallback(S32, LLScrollbar*);
-
-	virtual BOOL postBuild();
-
-	BOOL	handleMouseDown	(S32 x, S32 y, MASK mask);
-	BOOL	handleKeyHere	(KEY key, MASK mask);
-	BOOL	handleScrollWheel( S32 x, S32 y, S32 clicks );
-
-	void	scrollToBottom	();
-
-	void	setHeaderVisibility(EShowItemHeader e);
-	EShowItemHeader	getHeaderVisibility() const { return mEShowItemHeader;};
 
+	virtual void init(LLSD& data);
 
+	virtual void draw();
 private:
-	void	reformatHistoryScrollItems(S32 width);
-	void	arrange					(S32 width, S32 height);
-
-	S32		calcRecuiredHeight		();
-	S32		getRecuiredHeight		() const { return mInnerRect.getHeight(); }
-
-	void	updateLayout			(S32 width, S32 height);
-
-	void	show_hide_scrollbar		(S32 width, S32 height);
-
-	void	showScrollbar			(S32 width, S32 height);
-	void	hideScrollbar			(S32 width, S32 height);
-
-	void	panelSetLeftTopAndSize	(LLView* panel, S32 left, S32 top, S32 width, S32 height);
-	void	panelShiftVertical		(LLView* panel,S32 delta);
-	void	shiftPanels				(S32 delta);
+	
+	std::string appendTime	();
 
 private:
-	std::vector<LLChatItemCtrl*> mItems;
+	std::string		mText;		// UTF-8 line of text
+	std::string		mFromName;	// agent or object name
+	LLUUID			mFromID;	// agent id or object id
+	EChatSourceType	mSourceType;
 
-	EShowItemHeader mEShowItemHeader;
 
-	LLRect			mInnerRect;
-	LLScrollbar*	mScrollbar;
+	std::vector<std::string> mMessages;
 
+	bool mIsDirty;
 };
 
+
 #endif
 
 
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index e6398dd47aba2f64e8a16ac2c0447dfacdc4fc13..bd0c36b44a2ac9142725c7002896fae72d2f4c39 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
 
 	// iterate through each block of text that has been added
 	y -= mLineSpacing;
-	for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
+	for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
 	{
 		// display the text for this block
 		S32 num_chars = *it - start;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 20c44d5b114d74221f9837aa3909f90b8c566141..98e492cadae28f27c7b8547bc4d51cec6fa937ee 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -49,6 +49,7 @@
 #include "llvoicecontrolpanel.h"
 #include "llgroupmgr.h"
 #include "llnotificationmanager.h"
+#include "lltransientfloatermgr.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
 static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
@@ -243,26 +244,36 @@ void LLIMChiclet::draw()
 LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
 {
 	EType				type	= TYPE_UNKNOWN;
-	LLFloaterIMPanel*	im		= NULL;
 
 	if(session_id.isNull())
 		return type;
 
-	if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
+	EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
+	if (IM_COUNT == im_type)
 	{
 		llassert_always(0 && "IM session not found"); // should never happen
 		return type;
 	}
 
-	switch(im->getDialogType())
+	switch(im_type)
 	{
 	case IM_NOTHING_SPECIAL:
+	case IM_SESSION_P2P_INVITE:
 		type = TYPE_IM;
 		break;
 	case IM_SESSION_GROUP_START:
 	case IM_SESSION_INVITE:
-		type = TYPE_GROUP;
+		if (gAgent.isInGroup(session_id))
+		{
+			type = TYPE_GROUP;
+		}
+		else
+		{
+			type = TYPE_AD_HOC;
+		}
 		break;
+	case IM_SESSION_CONFERENCE_START:
+		type = TYPE_AD_HOC;
 	default:
 		break;
 	}
@@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
 
 	avatar_icon.name("avatar_icon");
 	avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+
+	// *NOTE dzaporozhan
+	// Changed icon height from 25 to 24 to fix ticket EXT-794.
+	// In some cases(after changing UI scale) 25 pixel height icon was 
+	// drawn incorrectly, i'm not sure why.
 	avatar_icon.rect(LLRect(0, 24, 25, 0));
 	avatar_icon.mouse_opaque(false);
 
@@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
 	rect(LLRect(0, 25, 45, 0));
 
 	group_icon.name("group_icon");
+	
+	// *NOTE dzaporozhan
+	// Changed icon height from 25 to 24 to fix ticket EXT-794.
+	// In some cases(after changing UI scale) 25 pixel height icon was 
+	// drawn incorrectly, i'm not sure why.
 	group_icon.rect(LLRect(0, 24, 25, 0));
 
 	unread_notifications.name("unread");
@@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
 	speak_params.rect(speak_rect);
 	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
 	addChild(mSpeakBtn);
+	LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
 
 	mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
 	mSpeakBtn->setToggleState(FALSE);
@@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
 	show_params.rect(show_rect);
 	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
 	addChild(mShowBtn);
+	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
 
 	mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
 	mShowBtn->setToggleState(FALSE);
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 316348cf1d4507d402992c86f4d267e14d321afd..ef47b543331fa7f51eb6bafa8cc990f0c13b58ed 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -275,7 +275,8 @@ class LLIMChiclet : public LLChiclet
 	enum EType {
 		TYPE_UNKNOWN,
 		TYPE_IM,
-		TYPE_GROUP
+		TYPE_GROUP,
+		TYPE_AD_HOC
 	};
 	
 	/*virtual*/ ~LLIMChiclet() {};
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 99576947279bfcd87ca5be35edae4960c621e452..979a1a9a60a2cbff7657518151475029aabede3c 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -125,7 +125,7 @@ LLCurrencyUIManager::Impl::Impl(LLPanel& dialog)
 	mUserCurrencyBuy(2000), // note, this is a default, real value set in llfloaterbuycurrency.cpp
 	mUserEnteredCurrencyBuy(false),
 	mSiteCurrencyEstimated(false),
-	  mSiteCurrencyEstimatedCost(0),
+	mSiteCurrencyEstimatedCost(0),
 	mBought(false),
 	mTransactionType(TransactionNone), mTransaction(0),
 	mCurrencyChanged(false)
@@ -394,7 +394,7 @@ void LLCurrencyUIManager::Impl::updateUI()
 		}
 	}
 
-	mPanel.childSetTextArg("currency_est", "[USD]", llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
+	mPanel.childSetTextArg("currency_est", "[LOCALAMOUNT]", "US$ " + llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
 	mPanel.childSetVisible("currency_est", mSiteCurrencyEstimated && mUserCurrencyBuy > 0);
 
 	if (mPanel.childIsEnabled("buy_btn")
@@ -478,7 +478,7 @@ void LLCurrencyUIManager::buy(const std::string& buy_msg)
 
 	LLUIString msg = buy_msg;
 	msg.setArg("[LINDENS]", llformat("%d", impl.mUserCurrencyBuy));
-	msg.setArg("[USD]", llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
+	msg.setArg("[LOCALAMOUNT]", "US$ " + llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
 	LLConfirmationManager::confirm(impl.mSiteConfirm,
 								   msg,
 								   impl,
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 4cf12a1533d0792637eb30b0015bafff8ca2b224..069155c25590b2c208b7eeaa2e71a339087cbd48 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -960,6 +960,30 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
 	return retval;
 }
 
+const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
+//static 
+S32 LLDrawable::getMinVisFrameRange()
+{
+	return MIN_VIS_FRAME_RANGE ;
+}
+
+BOOL LLDrawable::isRecentlyVisible() const
+{
+	//currently visible or visible in the previous frame.
+	BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE)  ;
+
+	if(!vis)
+	{
+		LLSpatialGroup* group = getSpatialGroup();
+		if (group && group->isRecentlyVisible())
+		{
+			mVisible = sCurVisible;
+			vis = TRUE ;
+		}
+	}
+
+	return vis ;
+}
 
 BOOL LLDrawable::isVisible() const
 {
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 986440397b650a3894a678617e941ccc9fa48a3d..5a10b688da4290e6f2d81d0a28b8fd58b8617fce 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -78,7 +78,8 @@ class LLDrawable : public LLRefCount
 
 	BOOL isLight() const;
 
-	BOOL isVisible() const;		
+	BOOL isVisible() const;	
+	BOOL isRecentlyVisible() const;	
 	virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
 
 
@@ -278,7 +279,8 @@ class LLDrawable : public LLRefCount
 	S32				mQuietCount;
 
 	static S32 getCurrentFrame() { return sCurVisible; }
-	
+	static S32 getMinVisFrameRange();
+
 	void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
 	LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
 	
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index fc5b27dd1b355b887dc194ed46a538c86de13759..a5b0b056037ae4e1a0a0da4e13ca1ede206e2782 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -270,16 +270,34 @@ void LLFace::setTexture(LLViewerTexture* tex)
 	{
 		mTexture->removeFace(this) ;
 		removeAtlas() ;
-	}
+	}	
 	
 	mTexture = tex ;
-	
+
 	if(mTexture.notNull())
 	{
 		mTexture->addFace(this) ;
 	} 
 }
 
+void LLFace::switchTexture(LLViewerTexture* new_texture)
+{
+	if(mTexture == new_texture)
+	{
+		return ;
+	}
+
+	if(!new_texture)
+	{
+		llerrs << "Can not switch to a null texture." << llendl ;
+	}
+	new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
+
+	getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+	setTexture(new_texture) ;	
+	gPipeline.markTextured(getDrawable());
+}
+
 void LLFace::setTEOffset(const S32 te_offset)
 {
 	mTEOffset = te_offset;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index cafad5706c84bfcc64c3f3d9e471fa76f69d4aff..f6ffefcb7cd57a7e7e9a11780a101b92d629c9fe 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -89,6 +89,7 @@ class LLFace
 	U16				getGeomIndex()		const	{ return mGeomIndex; }		// index into draw pool
 	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool
 	void			setTexture(LLViewerTexture* tex) ;
+	void            switchTexture(LLViewerTexture* new_texture);
 	LLXformMatrix*	getXform()			const	{ return mXform; }
 	BOOL			hasGeometry()		const	{ return mGeomCount > 0; }
 	LLVector3		getPositionAgent()	const;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6b18984f885b2841cfcd12e87ec4bda0ca885a52..ea947a556561c212f4830ab417b23a732e30019f 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
 	LLMenuGL::showPopup(fav_button, menu, x, y);
 }
 
+BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
+	if(!handled && !gMenuHolder->hasVisibleMenu())
+	{
+		show_navbar_context_menu(this,x,y);
+		handled = true;
+	}
+	
+	return handled;
+}
 void copy_slurl_to_clipboard_cb(std::string& slurl)
 {
 	gClipboard.copyFromString(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 0be8de29a969c10ae45c1e31745d31da602a8d55..97117c3b4a0c45ebf480c7ba31da1ad0c406f922 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -62,7 +62,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 								   std::string& tooltip_msg);
 
 	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask);
-
+	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	// LLInventoryObserver observer trigger
 	virtual void changed(U32 mask);
 	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 0107cb6fe2034f0b501e77ff8d0a921542921ee1..5c4b8552a659eebfb8f60340184d020969d683cc 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -159,6 +159,9 @@ void LLFloaterBuyCurrencyUI::draw()
 		updateUI();
 	}
 
+	// disable the Buy button when we are not able to buy
+	childSetEnabled("buy_btn", mManager.canBuy());
+
 	LLFloater::draw();
 }
 
@@ -194,29 +197,19 @@ void LLFloaterBuyCurrencyUI::updateUI()
 	// error section
 	if (hasError)
 	{
-		mChildren.setBadge(std::string("step_error"), LLViewChildren::BADGE_ERROR);
-		
-		LLTextBox* message = getChild<LLTextBox>("error_message");
-		if (message)
-		{
-			message->setVisible(true);
-			message->setWrappedText(mManager.errorMessage());
-		}
-
-		childSetVisible("error_web", !mManager.errorURI().empty());
-		if (!mManager.errorURI().empty())
-		{
-			childHide("getting_data");
-		}
+		childHide("normal_background");
+		childShow("error_background");
+		childShow("cannot_buy_message");
+		childShow("error_web");
 	}
 	else
 	{
-		childHide("step_error");
-		childHide("error_message");
+		childShow("normal_background");
+		childHide("error_background");
+		childHide("cannot_buy_message");
 		childHide("error_web");
 	}
-	
-	
+
 	//  currency
 	childSetVisible("contacting", false);
 	childSetVisible("buy_action", false);
@@ -224,8 +217,6 @@ void LLFloaterBuyCurrencyUI::updateUI()
 	
 	if (!hasError)
 	{
-		mChildren.setBadge(std::string("step_1"), LLViewChildren::BADGE_NOTE);
-
 		if (mManager.buying())
 		{
 			childSetVisible("contacting", true);
@@ -286,9 +277,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
 		childHide("purchase_warning_notenough");
 	}
 	
-	childSetEnabled("buy_btn", mManager.canBuy());
-
-	if (!mManager.canBuy() && !childIsVisible("error_web"))
+	childHide("getting_data");
+	if (!mManager.canBuy() && !hasError)
 	{
 		childShow("getting_data");
 	}
@@ -298,10 +288,6 @@ void LLFloaterBuyCurrencyUI::onClickBuy()
 {
 	mManager.buy(getString("buy_currency"));
 	updateUI();
-	// JC: updateUI() doesn't get called again until progress is made
-	// with transaction processing, so the "Purchase" button would be
-	// left enabled for some time.  Pre-emptively disable.
-	childSetEnabled("buy_btn", false);
 }
 
 void LLFloaterBuyCurrencyUI::onClickCancel()
@@ -311,7 +297,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
 
 void LLFloaterBuyCurrencyUI::onClickErrorWeb()
 {
-	LLWeb::loadURLExternal(mManager.errorURI());
+	LLWeb::loadURLExternal(getString("account_website"));
 	closeFloater();
 }
 
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 14fb93df6144c115a79f7cb400d02b189cde4f48..ca43f41d05b6509423743c641b2f512f09852cd5 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -66,7 +66,6 @@
 #include "lllogchat.h"
 #include "lltexteditor.h"
 #include "lltextparser.h"
-#include "llfloaterhtml.h"
 #include "llweb.h"
 #include "llstylemap.h"
 
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index 05ea800d0ef58b7c01db3fd89a23516739495a63..dea656b0e49d2caf2d0da56eb120188340eba1a5 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
 			{
 				// only LLFloaterIMPanels are called "im_floater"
 				LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
-				if (im_floaterp->getVoiceChannel()  == LLVoiceChannel::getCurrentVoiceChannel())
+				LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
+				if (voice_channel  == LLVoiceChannel::getCurrentVoiceChannel())
 				{
 					return im_floaterp;
 				}
diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b0b5ed5e094c6054834eb2c8753829c2968d7a9
--- /dev/null
+++ b/indra/newview/llfloaterhelpbrowser.cpp
@@ -0,0 +1,142 @@
+/** 
+ * @file llfloaterhelpbrowser.cpp
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ * 
+ * Copyright (c) 2006-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 "llfloaterhelpbrowser.h"
+
+#include "llfloaterreg.h"
+#include "llpluginclassmedia.h"
+#include "llmediactrl.h"
+#include "llviewerwindow.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+#include "llui.h"
+
+#include "llurlhistory.h"
+#include "llmediactrl.h"
+#include "llviewermedia.h"
+
+
+LLFloaterHelpBrowser::LLFloaterHelpBrowser(const LLSD& key)
+	: LLFloater(key)
+{
+	// really really destroy the help browser when it's closed, it'll be recreated.
+	// *TODO: when onClose() is resurrected as a virtual, this bind can go away.
+	mCloseSignal.connect(boost::bind(&LLFloaterHelpBrowser::onClose, this));
+}
+
+BOOL LLFloaterHelpBrowser::postBuild()
+{
+	mBrowser = getChild<LLMediaCtrl>("browser");
+	mBrowser->addObserver(this);
+
+	childSetAction("open_browser", onClickOpenWebBrowser, this);
+
+	buildURLHistory();
+	return TRUE;
+}
+
+void LLFloaterHelpBrowser::buildURLHistory()
+{
+	// Get all of the entries in the "browser" collection
+	LLSD browser_history = LLURLHistory::getURLHistory("browser");
+
+	// initialize URL history in the plugin
+	LLPluginClassMedia *plugin = mBrowser->getMediaPlugin();
+	if (plugin)
+	{
+		plugin->initializeUrlHistory(browser_history);
+	}
+}
+
+void LLFloaterHelpBrowser::onClose()
+{
+	destroy(); // really destroy this dialog on closure, it's relatively heavyweight.
+}
+
+void LLFloaterHelpBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+	if(event == MEDIA_EVENT_LOCATION_CHANGED)
+	{
+		setCurrentURL(self->getLocation());
+	}
+	else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+	{
+		// nothing yet
+	}
+}
+
+void LLFloaterHelpBrowser::setCurrentURL(const std::string& url)
+{
+	mCurrentURL = url;
+
+	// redirects will navigate momentarily to about:blank, don't add to history
+	if (mCurrentURL != "about:blank")
+	{
+		// Serialize url history
+		LLURLHistory::removeURL("browser", mCurrentURL);
+		LLURLHistory::addURL("browser", mCurrentURL);
+	}
+}
+
+//static 
+void LLFloaterHelpBrowser::onClickClose(void* user_data)
+{
+	LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
+
+	self->closeFloater();
+}
+
+//static 
+void LLFloaterHelpBrowser::onClickOpenWebBrowser(void* user_data)
+{
+	LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
+
+	std::string url = self->mCurrentURL.empty() ? 
+		self->mBrowser->getHomePageUrl() :
+		self->mCurrentURL;
+	LLWeb::loadURLExternal(url);
+}
+
+void LLFloaterHelpBrowser::openMedia(const std::string& media_url)
+{
+	mBrowser->setHomePageUrl(media_url);
+	//mBrowser->navigateTo("data:text/html;charset=utf-8,I'd really love to be going to:<br><b>" + media_url + "</b>"); // tofu HACK for debugging =:)
+	mBrowser->navigateTo(media_url);
+	setCurrentURL(media_url);
+}
+
+void LLFloaterHelpBrowser::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
+{
+	mBrowser->navigateToLocalPage(subdir, filename_in);
+}
diff --git a/indra/newview/llfloaterhelpbrowser.h b/indra/newview/llfloaterhelpbrowser.h
new file mode 100644
index 0000000000000000000000000000000000000000..14a276b4283d324276b258bdd3904a02c4049216
--- /dev/null
+++ b/indra/newview/llfloaterhelpbrowser.h
@@ -0,0 +1,72 @@
+/** 
+ * @file llfloatermediabrowser.h
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ * 
+ * Copyright (c) 2006-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_LLFLOATERHELPBROWSER_H
+#define LL_LLFLOATERHELPBROWSER_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+
+
+class LLMediaCtrl;
+
+class LLFloaterHelpBrowser : 
+	public LLFloater, 
+	public LLViewerMediaObserver
+{
+ public:
+	LLFloaterHelpBrowser(const LLSD& key);
+
+	/*virtual*/ BOOL postBuild();
+	void onClose();
+
+	// inherited from LLViewerMediaObserver
+	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+	void openMedia(const std::string& media_url);
+
+	void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
+	
+ private:
+	void buildURLHistory();
+	void setCurrentURL(const std::string& url);
+
+	static void onClickClose(void* user_data);
+	static void onClickOpenWebBrowser(void* user_data);
+
+ private:
+	LLMediaCtrl* mBrowser;
+	std::string mCurrentURL;
+};
+
+#endif  // LL_LLFLOATERHELPBROWSER_H
+
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 27eb12b9ccca012bce6a1b94a04e0efea014043d..116286329c4f223e161d73e917728dd19c940398 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -1169,7 +1169,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p)
 	mScroller(NULL),
 	mSortOrderSetting(p.sort_order_setting),
 	mInventory(p.inventory),
-	mAllowMultiSelect(p.allow_multi_select)
+	mAllowMultiSelect(p.allow_multi_select),
+	mHasInventoryConnection(false)
 {
 	// contex menu callbacks
 	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
@@ -1230,9 +1231,10 @@ BOOL LLInventoryPanel::postBuild()
 	mInventoryObserver = new LLInventoryPanelObserver(this);
 	mInventory->addObserver(mInventoryObserver);
 	// build view of inventory if inventory ready, otherwise wait for modelChanged() callback
-	if (mInventory->isInventoryUsable())
+	if (mInventory->isInventoryUsable() && !mHasInventoryConnection)
 	{
 		rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
+		mHasInventoryConnection = true;
 	}
 
 	// bit of a hack to make sure the inventory is open.
@@ -1332,9 +1334,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	bool handled = false;
 
 	// inventory just initialized, do complete build
-	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty())
+	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
 	{
 		rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
+		mHasInventoryConnection = true;
 		return;
 	}
 
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index a40efe020bf1cdb705b6b7071e8e80bceb5dccaf..1aaac74c870e9c1cce3a93f66325b672f26a6a91 100644
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
@@ -179,6 +179,7 @@ class LLInventoryPanel : public LLPanel
 	LLScrollContainer*			mScroller;
 	BOOL 						mAllowMultiSelect;
 	std::string					mSortOrderSetting;
+	bool						mHasInventoryConnection;
 };
 
 class LLFloaterInventory;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index e5f5e8eedb0a37b987214fe544f709ef326c5bf6..3fe7d8d9da2a5ef2d9118b733a82fd7e0f960f24 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1043,7 +1043,7 @@ BOOL LLPanelLandObjects::postBuild()
 	mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
 	mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
 
-	mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
+	mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(onLostFocus, _1, this));
 	mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
 	childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);
 	
diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp
index c580cdef8aa1b78c65b35b30e936fa4bf795392a..9b7f3305e5cc1d4fb6c7cbd04498d71a2329a080 100644
--- a/indra/newview/llfloatermediabrowser.cpp
+++ b/indra/newview/llfloatermediabrowser.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file llfloaterhtmlhelp.cpp
- * @brief HTML Help floater - uses embedded web browser control
+ * @file llfloatermediabrowser.cpp
+ * @brief media browser floater - uses embedded media browser control
  *
  * $LicenseInfo:firstyear=2006&license=viewergpl$
  * 
@@ -33,7 +33,6 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfloatermediabrowser.h"
-#include "llfloaterhtml.h"
 
 #include "llfloaterreg.h"
 #include "llparcel.h"
@@ -147,7 +146,10 @@ void LLFloaterMediaBrowser::buildURLHistory()
 	}
 
 	// initialize URL history in the plugin
-	mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
+	if(mBrowser && mBrowser->getMediaPlugin())
+	{
+		mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
+	}
 }
 
 std::string LLFloaterMediaBrowser::getSupportURL()
@@ -330,69 +332,3 @@ void LLFloaterMediaBrowser::openMedia(const std::string& media_url)
 	mBrowser->navigateTo(media_url);
 	setCurrentURL(media_url);
 }
-////////////////////////////////////////////////////////////////////////////////
-//
-
-LLViewerHtmlHelp gViewerHtmlHelp;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLViewerHtmlHelp::LLViewerHtmlHelp()
-{
-
-	LLUI::setHtmlHelp(this);
-}
-
-LLViewerHtmlHelp::~LLViewerHtmlHelp()
-{
-
-	LLUI::setHtmlHelp(NULL);
-}
-
-void LLViewerHtmlHelp::show()
-{
-	show("");
-}
-
-void LLViewerHtmlHelp::show(std::string url)
-{
-	LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
-	floater_html->setVisible(FALSE);
-
-	if (url.empty())
-	{
-		url = floater_html->getSupportURL();
-	}
-
-	if (gSavedSettings.getBOOL("UseExternalBrowser"))
-	{
-		LLSD notificationData;
-		notificationData["url"] = url;
-
-		LLNotifications::instance().add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL);	    
-		floater_html->closeFloater();
-	}
-	else
-	{
-		// don't wait, just do it
-		floater_html->setVisible(TRUE);
-		floater_html->openMedia(url);
-	}
-}
-
-// static 
-bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response)
-{
-	LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
-	floater_html->setVisible(FALSE);
-	std::string url = floater_html->getSupportURL();
-	S32 option = LLNotification::getSelectedOption(notification, response);
-	if (option == 0)
-	{
-		LLWeb::loadURL(url);
-	}
-	floater_html->closeFloater();
-	return false;
-}
-
diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h
index 76e8b517a05de8b5aa116c059fb837a181106896..c315f9e7978d375d79656261656fe24f4eea587e 100644
--- a/indra/newview/llfloatermediabrowser.h
+++ b/indra/newview/llfloatermediabrowser.h
@@ -1,6 +1,6 @@
 /** 
  * @file llfloatermediabrowser.h
- * @brief HTML Help floater - uses embedded web browser control
+ * @brief media browser floater - uses embedded media browser control
  *
  * $LicenseInfo:firstyear=2006&license=viewergpl$
  * 
@@ -33,23 +33,9 @@
 #ifndef LL_LLFLOATERMEDIABROWSER_H
 #define LL_LLFLOATERMEDIABROWSER_H
 
-#include "llhtmlhelp.h"
 #include "llfloater.h"
 #include "llmediactrl.h"
 
-class LLViewerHtmlHelp : public LLHtmlHelp
-{
-public:
-	LLViewerHtmlHelp();
-	virtual ~LLViewerHtmlHelp();
-
-	/*virtual*/ void show();
-	/*virtual*/ void show(std::string start_url);
-	void show(std::string start_url, std::string title);
-
-	static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response);
-
-};
 
 class LLComboBox;
 class LLMediaCtrl;
@@ -93,7 +79,5 @@ class LLFloaterMediaBrowser :
 	std::string mCurrentURL;
 };
 
-extern LLViewerHtmlHelp gViewerHtmlHelp;
-
 #endif  // LL_LLFLOATERMEDIABROWSER_H
 
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..811cc26efbb2358d1ca8bf58037aaaefd421d46c
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -0,0 +1,249 @@
+/** 
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+#include "llfloatermediasettings.h"
+#include "llpanelmediasettingsgeneral.h"
+#include "llpanelmediasettingssecurity.h"
+#include "llpanelmediasettingspermissions.h"
+#include "llviewercontrol.h"
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llselectmgr.h"
+
+LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+// 
+LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)
+	: LLFloater(key),
+	mTabContainer(NULL),
+	mPanelMediaSettingsGeneral(NULL),
+	mPanelMediaSettingsSecurity(NULL),
+	mPanelMediaSettingsPermissions(NULL),
+	mWaitingToClose( false )
+{
+//	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterMediaSettings::~LLFloaterMediaSettings()
+{
+	if ( mPanelMediaSettingsGeneral )
+	{
+		delete mPanelMediaSettingsGeneral;
+		mPanelMediaSettingsGeneral = NULL;
+	}
+
+	if ( mPanelMediaSettingsSecurity )
+	{
+		delete mPanelMediaSettingsSecurity;
+		mPanelMediaSettingsSecurity = NULL;
+	}
+
+	if ( mPanelMediaSettingsPermissions )
+	{
+		delete mPanelMediaSettingsPermissions;
+		mPanelMediaSettingsPermissions = NULL;
+	}
+
+	sInstance = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterMediaSettings::postBuild()
+{
+	mCloseSignal.connect(boost::bind(&LLFloaterMediaSettings::onClose, this));
+
+	mApplyBtn = getChild<LLButton>("Apply");
+	mApplyBtn->setClickedCallback(onBtnApply, this);
+		
+	mCancelBtn = getChild<LLButton>("Cancel");
+	mCancelBtn->setClickedCallback(onBtnCancel, this);
+
+	mOKBtn = getChild<LLButton>("OK");
+	mOKBtn->setClickedCallback(onBtnOK, this);
+			
+	mTabContainer = getChild<LLTabContainer>( "tab_container" );
+	
+	mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral();
+	mTabContainer->addTabPanel( 
+			LLTabContainer::TabPanelParams().
+			panel(mPanelMediaSettingsGeneral));
+	mPanelMediaSettingsGeneral->setParent( this );
+
+	// note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+	// 'permissions' not changed to 'controls' since we don't want to change 
+	// shared files in server code and keeping everything the same seemed best.
+	mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions();
+	mTabContainer->addTabPanel( 
+			LLTabContainer::TabPanelParams().
+			panel(mPanelMediaSettingsPermissions));
+
+	mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity();
+	mTabContainer->addTabPanel( 
+			LLTabContainer::TabPanelParams().
+			panel(mPanelMediaSettingsSecurity));
+		
+	// restore the last tab viewed from persistance variable storage
+	if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab")))
+	{
+		mTabContainer->selectFirstTab();
+	};
+
+	sInstance = this;
+
+	return TRUE;
+}
+
+//static 
+LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance()
+{
+	if ( !sInstance )
+	{
+		sInstance = (LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings"));
+	}
+	
+	return sInstance;
+}
+
+//static 
+void LLFloaterMediaSettings::apply()
+{
+	
+    LLSD settings;
+    sInstance->mPanelMediaSettingsGeneral->getValues( settings );
+    sInstance->mPanelMediaSettingsSecurity->getValues( settings );
+    sInstance->mPanelMediaSettingsPermissions->getValues( settings );
+	LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA );
+    LLSelectMgr::getInstance()->selectionSetMediaData(settings);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onClose()
+{
+	if(mPanelMediaSettingsGeneral)
+	{
+		mPanelMediaSettingsGeneral->onClose();
+	}
+	LLFloaterReg::hideInstance("whitelist_entry");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static 
+void LLFloaterMediaSettings::initValues( const LLSD& media_settings )
+{
+	sInstance->clearValues();
+	// update all panels with values from simulator
+	sInstance->mPanelMediaSettingsGeneral->
+		initValues( sInstance->mPanelMediaSettingsGeneral, media_settings );
+
+	sInstance->mPanelMediaSettingsSecurity->
+		initValues( sInstance->mPanelMediaSettingsSecurity, media_settings );
+
+	sInstance->mPanelMediaSettingsPermissions->
+		initValues( sInstance->mPanelMediaSettingsPermissions, media_settings );
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// 
+void LLFloaterMediaSettings::commitFields()
+{
+	if (hasFocus())
+	{
+		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+		if (cur_focus->acceptsTextInput())
+		{
+			cur_focus->onCommit();
+		};
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static 
+void LLFloaterMediaSettings::clearValues()
+{
+	// clean up all panels before updating
+	sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral);
+	sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity);
+	sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions);	
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnOK( void* userdata )
+{
+	sInstance->commitFields();
+
+	sInstance->apply();
+
+	sInstance->closeFloater();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnApply( void* userdata )
+{
+	sInstance->commitFields();
+
+	sInstance->apply();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnCancel( void* userdata )
+{
+ 	sInstance->closeFloater(); 
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click)
+{
+	LLTabContainer* self = (LLTabContainer*)user_data;
+	gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterMediaSettings::enableOkApplyBtns( bool enable )
+{
+	setCtrlsEnabled( enable );
+	childSetEnabled( "OK", enable );
+	childSetEnabled( "Apply", enable );
+}
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..b95c590346fd8c3c54e87ea6cda8906256b6b97a
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.h
@@ -0,0 +1,81 @@
+/** 
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-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_LLFLOATERMEDIASETTINGS_H
+#define LL_LLFLOATERMEDIASETTINGS_H
+
+#include "llfloater.h"
+#include "lltabcontainer.h"
+
+class LLPanelMediaSettingsGeneral;
+class LLPanelMediaSettingsSecurity;
+class LLPanelMediaSettingsPermissions;
+
+class LLFloaterMediaSettings : 
+	public LLFloater
+{
+public: 
+	LLFloaterMediaSettings(const LLSD& key);
+	~LLFloaterMediaSettings();
+
+	virtual BOOL postBuild();
+	static LLFloaterMediaSettings* getInstance();
+	static void apply();
+	static void initValues( const LLSD& media_settings );
+	static void clearValues();
+	void enableOkApplyBtns( bool enable );
+	LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
+
+protected:
+	LLButton *mOKBtn;
+	LLButton *mCancelBtn;
+	LLButton *mApplyBtn;
+
+	LLTabContainer *mTabContainer;
+	LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral;
+	LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;
+	LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions;
+
+	void		onClose();
+	static void onBtnOK(void*);
+	static void onBtnCancel(void*);
+	static void onBtnApply(void*);
+	static void onTabChanged(void* user_data, bool from_click);
+	void commitFields();
+
+	static LLFloaterMediaSettings* sInstance;
+
+private:
+	bool mWaitingToClose;
+};
+
+#endif  // LL_LLFLOATERMEDIASETTINGS_H
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index fbc0ff3cf57b827bcac34568c8c6eb9cfef194a7..938370b732ada65e55d6739432357141f3b59136 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -106,7 +106,7 @@ BOOL LLFloaterPostcard::postBuild()
 	childSetValue("name_form", LLSD(name_string));
 
 	// For the first time a user focusess to .the msg box, all text will be selected.
-	getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(onMsgFormFocusRecieved, this);
+	getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(onMsgFormFocusRecieved, _1, this));
 	
 	childSetFocus("to_form", TRUE);
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 761b5c9219bb9846d856631be4733b90873b5a1d..57c043a1e02c20e6b7d61788759e4eae555e89b8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -195,8 +195,8 @@ void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
 
 viewer_media_t get_web_media()
 {
-	viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
-	
+	viewer_media_t media_source = LLViewerMedia::newMediaImpl(LLUUID::null);
+	media_source->initializeMedia("text/html");
 	return media_source;
 }
 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 4d154c4cd3ad341c600b215a2c0a186d342f00e8..3dcdc2f56efc2004a914b2e56f7cf6098e8e9bed 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llfloaterreporter.cpp
- * @brief Bug and abuse reports.
+ * @brief Abuse reports.
  *
  * $LicenseInfo:firstyear=2002&license=viewergpl$
  * 
@@ -220,8 +220,7 @@ LLFloaterReporter::~LLFloaterReporter()
 void LLFloaterReporter::draw()
 {
 	// this is set by a static callback sometime after the dialog is created.
-	// Only disable screenshot for abuse reports to estate owners - bug reports always
-	// allow screenshots to be taken.
+	// Only disable screenshot for abuse reports to estate owners
 	if ( mEmailToEstateOwner )
 	{
 		childSetValue("screen_check", FALSE );
@@ -479,15 +478,6 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
 	if (f)
 	{
 		f->setReportType(report_type);
-
-		if (report_type == BUG_REPORT)
-		{
- 			LLNotifications::instance().add("HelpReportBug");
-		}
-		else
-		{
-			// popup for abuse reports is triggered elsewhere
-		}
 	}
 }
 
@@ -528,14 +518,7 @@ bool LLFloaterReporter::validateReport()
 	U8 category = (U8)category_sd.asInteger();
 	if (category == 0)
 	{
-		if ( mReportType != BUG_REPORT )
-		{
-			LLNotifications::instance().add("HelpReportAbuseSelectCategory");
-		}
-		else
-		{
-			LLNotifications::instance().add("HelpReportBugSelectCategory");
-		}
+		LLNotifications::instance().add("HelpReportAbuseSelectCategory");
 		return false;
 	}
 
@@ -561,27 +544,13 @@ bool LLFloaterReporter::validateReport()
 
 	if ( childGetText("summary_edit").empty() )
 	{
-		if ( mReportType != BUG_REPORT )
-		{
-			LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
-		}
-		else
-		{
-			LLNotifications::instance().add("HelpReportBugSummaryEmpty");
-		}
+		LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
 		return false;
 	};
 
 	if ( childGetText("details_edit") == mDefaultSummary )
 	{
-		if ( mReportType != BUG_REPORT )
-		{
-			LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
-		}
-		else
-		{
-			LLNotifications::instance().add("HelpReportBugDetailsEmpty");
-		}
+		LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
 		return false;
 	};
 	return true;
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index f363b9531efcb642847cef388ec875e886b5ed08..7e8f05e3fc663d93470b832561eedc380b6fa924 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -1,7 +1,7 @@
 /** 
  * @file llfloaterreporter.h
  * @author Andrew Meadows
- * @brief Bug and abuse reports.
+ * @brief Abuse reports.
  *
  * $LicenseInfo:firstyear=2006&license=viewergpl$
  * 
@@ -48,7 +48,7 @@ class LLMeanCollisionData;
 struct LLResourceData;
 
 // these flags are used to label info requests to the server
-const U32 BUG_REPORT_REQUEST 		= 0x01 << 0;
+//const U32 BUG_REPORT_REQUEST 		= 0x01 << 0; // DEPRECATED
 const U32 COMPLAINT_REPORT_REQUEST 	= 0x01 << 1;
 const U32 OBJECT_PAY_REQUEST		= 0x01 << 2;
 
@@ -73,7 +73,7 @@ enum EReportType
 {
 	NULL_REPORT = 0,		// don't use this value anywhere
 	UNKNOWN_REPORT = 1,
-	BUG_REPORT = 2,
+	//BUG_REPORT = 2, // DEPRECATED
 	COMPLAINT_REPORT = 3,
 	CS_REQUEST_REPORT = 4
 };
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index f334344279c8c34a4fd7e5fee3a98f0689f50f1b..7dc29379e4d06df3783324dd2c8829b50cf45ea1 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -44,9 +44,11 @@
 #include "llcombobox.h"
 #include "lldraghandle.h"
 #include "llfloaterbuildoptions.h"
+#include "llfloatermediasettings.h"
 #include "llfloateropenobject.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
+#include "llmediaentry.h"
 #include "llmenugl.h"
 #include "llpanelcontents.h"
 #include "llpanelface.h"
@@ -97,7 +99,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
 };
 
 // Local prototypes
-void commit_select_component(LLUICtrl *ctrl, void *data);
+void commit_select_component(void *data);
 void click_show_more(void*);
 void click_popup_info(void*);
 void click_popup_done(void*);
@@ -105,15 +107,14 @@ void click_popup_minimize(void*);
 void click_popup_rotate_left(void*);
 void click_popup_rotate_reset(void*);
 void click_popup_rotate_right(void*);
-void commit_slider_dozer_size(LLUICtrl *, void*);
-void commit_slider_dozer_force(LLUICtrl *, void*);
+void commit_slider_dozer_force(LLUICtrl *);
 void click_apply_to_selection(void*);
-void commit_radio_group_focus(LLUICtrl* ctrl, void* data);
-void commit_radio_group_move(LLUICtrl* ctrl, void* data);
-void commit_radio_group_edit(LLUICtrl* ctrl, void* data);
-void commit_radio_group_land(LLUICtrl* ctrl, void* data);
-void commit_grid_mode(LLUICtrl *, void*);
-void commit_slider_zoom(LLUICtrl *, void*);
+void commit_radio_group_focus(LLUICtrl* ctrl);
+void commit_radio_group_move(LLUICtrl* ctrl);
+void commit_radio_group_edit(LLUICtrl* ctrl);
+void commit_radio_group_land(LLUICtrl* ctrl);
+void commit_grid_mode(LLUICtrl *);
+void commit_slider_zoom(LLUICtrl *ctrl);
 
 
 //static
@@ -210,43 +211,28 @@ BOOL	LLFloaterTools::postBuild()
 	getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
 
 	LLRect rect;
-	mBtnFocus = getChild<LLButton>("button focus");//btn;
-	childSetAction("button focus",LLFloaterTools::setEditTool, (void*)LLToolCamera::getInstance());
-	mBtnMove = getChild<LLButton>("button move");
-	childSetAction("button move",LLFloaterTools::setEditTool, (void*)LLToolGrab::getInstance());
-	mBtnEdit = getChild<LLButton>("button edit");
-	childSetAction("button edit",LLFloaterTools::setEditTool, (void*)LLToolCompTranslate::getInstance());
-	mBtnCreate = getChild<LLButton>("button create");
-	childSetAction("button create",LLFloaterTools::setEditTool, (void*)LLToolCompCreate::getInstance());
-	mBtnLand = getChild<LLButton>("button land" );
-	childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance());
-	mTextStatus = getChild<LLTextBox>("text status");
-
-	childSetCommitCallback("slider zoom",commit_slider_zoom,this);
-
-	mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
-	childSetCommitCallback("focus_radio_group", commit_radio_group_focus, this);
-
-	mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
-	childSetCommitCallback("move_radio_group", commit_radio_group_move, this);
-
-	mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
-	childSetCommitCallback("edit_radio_group", commit_radio_group_edit, this);
-
-	mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
+	mBtnFocus			= getChild<LLButton>("button focus");//btn;
+	mBtnMove			= getChild<LLButton>("button move");
+	mBtnEdit			= getChild<LLButton>("button edit");
+	mBtnCreate			= getChild<LLButton>("button create");
+	mBtnLand			= getChild<LLButton>("button land" );
+	mTextStatus			= getChild<LLTextBox>("text status");
+	mRadioGroupFocus	= getChild<LLRadioGroup>("focus_radio_group");
+	mRadioGroupMove		= getChild<LLRadioGroup>("move_radio_group");
+	mRadioGroupEdit		= getChild<LLRadioGroup>("edit_radio_group");
+	mBtnGridOptions		= getChild<LLButton>("Options...");
+	
+	mCheckSelectIndividual	= getChild<LLCheckBoxCtrl>("checkbox edit linked parts");	
 	childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
-	childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
-	mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
+	mCheckSnapToGrid		= getChild<LLCheckBoxCtrl>("checkbox snap to grid");
 	childSetValue("checkbox snap to grid",(BOOL)gSavedSettings.getBOOL("SnapEnabled"));
-	mBtnGridOptions = getChild<LLButton>("Options...");
-	childSetAction("Options...",onClickGridOptions, this);
-	mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
+	mCheckStretchUniform	= getChild<LLCheckBoxCtrl>("checkbox uniform");
 	childSetValue("checkbox uniform",(BOOL)gSavedSettings.getBOOL("ScaleUniform"));
-	mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
+	mCheckStretchTexture	= getChild<LLCheckBoxCtrl>("checkbox stretch textures");
 	childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
-	mTextGridMode = getChild<LLTextBox>("text ruler mode");
-	mComboGridMode = getChild<LLComboBox>("combobox grid mode");
-	childSetCommitCallback("combobox grid mode",commit_grid_mode, this);
+	mTextGridMode			= getChild<LLTextBox>("text ruler mode");
+	mComboGridMode			= getChild<LLComboBox>("combobox grid mode");
+
 	//
 	// Create Buttons
 	//
@@ -271,18 +257,11 @@ BOOL	LLFloaterTools::postBuild()
 	mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
 	childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
 
-	mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
-	childSetCommitCallback("land_radio_group", commit_radio_group_land, this);
-
-	mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
-	childSetAction("button apply to selection",click_apply_to_selection,  (void*)0);
-
-	mSliderDozerSize = getChild<LLSlider>("slider brush size");
-	childSetCommitCallback("slider brush size", commit_slider_dozer_size,  (void*)0);
+	mRadioGroupLand			= getChild<LLRadioGroup>("land_radio_group");
+	mBtnApplyToSelection	= getChild<LLButton>("button apply to selection");
+	mSliderDozerSize		= getChild<LLSlider>("slider brush size");
 	childSetValue( "slider brush size", gSavedSettings.getF32("LandBrushSize"));
-	
-	mSliderDozerForce = getChild<LLSlider>("slider force");
-	childSetCommitCallback("slider force",commit_slider_dozer_force,  (void*)0);
+	mSliderDozerForce		= getChild<LLSlider>("slider force");
 	// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
 	childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce")));
 
@@ -369,6 +348,22 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
 	mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
 	
 	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE);
+	mCommitCallbackRegistrar.add("BuildTool.setTool",			boost::bind(&LLFloaterTools::setTool,this, _2));
+	mCommitCallbackRegistrar.add("BuildTool.commitZoom",		boost::bind(&commit_slider_zoom, _1));
+	mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus",	boost::bind(&commit_radio_group_focus, _1));
+	mCommitCallbackRegistrar.add("BuildTool.commitRadioMove",	boost::bind(&commit_radio_group_move,_1));
+	mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit",	boost::bind(&commit_radio_group_edit,_1));
+
+	mCommitCallbackRegistrar.add("BuildTool.selectComponent",	boost::bind(&commit_select_component, this));
+	mCommitCallbackRegistrar.add("BuildTool.gridOptions",		boost::bind(&LLFloaterTools::onClickGridOptions,this));
+	mCommitCallbackRegistrar.add("BuildTool.applyToSelection",	boost::bind(&click_apply_to_selection, this));
+	mCommitCallbackRegistrar.add("BuildTool.gridMode",			boost::bind(&commit_grid_mode,_1));
+	mCommitCallbackRegistrar.add("BuildTool.commitRadioLand",	boost::bind(&commit_radio_group_land,_1));
+	mCommitCallbackRegistrar.add("BuildTool.LandBrushForce",	boost::bind(&commit_slider_dozer_force,_1));
+	mCommitCallbackRegistrar.add("BuildTool.AddMedia",			boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
+	mCommitCallbackRegistrar.add("BuildTool.DeleteMedia",		boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
+	mCommitCallbackRegistrar.add("BuildTool.EditMedia",			boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
+
 }
 
 LLFloaterTools::~LLFloaterTools()
@@ -427,6 +422,7 @@ void LLFloaterTools::refresh()
 	mPanelObject->refresh();
 	mPanelVolume->refresh();
 	mPanelFace->refresh();
+	refreshMedia();
 	mPanelContents->refresh();
 	mPanelLandInfo->refresh();
 }
@@ -756,6 +752,7 @@ void LLFloaterTools::onClose()
 	LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
 
 	//gMenuBarView->setItemVisible("BuildTools", FALSE);
+	LLFloaterReg::hideInstance("media_settings");
 }
 
 void click_popup_info(void*)
@@ -767,7 +764,7 @@ void click_popup_done(void*)
 	handle_reset_view();
 }
 
-void commit_radio_group_move(LLUICtrl* ctrl, void* data)
+void commit_radio_group_move(LLUICtrl* ctrl)
 {
 	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 	std::string selected = group->getValue().asString();
@@ -788,7 +785,7 @@ void commit_radio_group_move(LLUICtrl* ctrl, void* data)
 	}
 }
 
-void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
+void commit_radio_group_focus(LLUICtrl* ctrl)
 {
 	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 	std::string selected = group->getValue().asString();
@@ -812,7 +809,7 @@ void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
 	}
 }
 
-void commit_slider_zoom(LLUICtrl *ctrl, void*)
+void commit_slider_zoom(LLUICtrl *ctrl)
 {
 	// renormalize value, since max "volume" level is 0.5 for some reason
 	F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
@@ -837,26 +834,19 @@ void click_popup_rotate_right(void*)
 	dialog_refresh_all();
 }
 
-
-void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
-{
-	F32 size = (F32)ctrl->getValue().asReal();
-	gSavedSettings.setF32("LandBrushSize", size);
-}
-
-void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
+void commit_slider_dozer_force(LLUICtrl *ctrl)
 {
 	// the slider is logarithmic, so we exponentiate to get the actual force multiplier
 	F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
 	gSavedSettings.setF32("LandBrushForce", dozer_force);
 }
 
-void click_apply_to_selection(void* user)
+void click_apply_to_selection(void*)
 {
 	LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
 }
 
-void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
+void commit_radio_group_edit(LLUICtrl *ctrl)
 {
 	S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
 
@@ -881,7 +871,7 @@ void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
 	gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
 }
 
-void commit_radio_group_land(LLUICtrl* ctrl, void* data)
+void commit_radio_group_land(LLUICtrl* ctrl)
 {
 	LLRadioGroup* group = (LLRadioGroup*)ctrl;
 	std::string selected = group->getValue().asString();
@@ -909,7 +899,7 @@ void commit_radio_group_land(LLUICtrl* ctrl, void* data)
 	}
 }
 
-void commit_select_component(LLUICtrl *ctrl, void *data)
+void commit_select_component(void *data)
 {
 	LLFloaterTools* floaterp = (LLFloaterTools*)data;
 
@@ -933,7 +923,7 @@ void commit_select_component(LLUICtrl *ctrl, void *data)
 	}
 }
 
-void commit_grid_mode(LLUICtrl *ctrl, void *data)   
+void commit_grid_mode(LLUICtrl *ctrl)   
 {   
 	LLComboBox* combo = (LLComboBox*)ctrl;   
     
@@ -948,10 +938,9 @@ void LLFloaterTools::setObjectType( LLPCode pcode )
 	gFocusMgr.setMouseCapture(NULL);
 }
 
-// static
-void LLFloaterTools::onClickGridOptions(void* data)
+
+void LLFloaterTools::onClickGridOptions()
 {
-	//LLFloaterTools* floaterp = (LLFloaterTools*)data;
 	LLFloaterReg::showInstance("build_options");
 	// RN: this makes grid options dependent on build tools window
 	//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
@@ -964,8 +953,558 @@ void LLFloaterTools::setEditTool(void* tool_pointer)
 	LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
 }
 
+void LLFloaterTools::setTool(const LLSD& user_data)
+{
+	std::string control_name = user_data.asString();
+	if(control_name == "Focus")
+		LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
+	else if (control_name == "Move" )
+		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
+	else if (control_name == "Edit" )
+		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
+	else if (control_name == "Create" )
+		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
+	else if (control_name == "Land" )
+		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
+	else
+		llwarns<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< llendl;
+}
+
 void LLFloaterTools::onFocusReceived()
 {
 	LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
 	LLFloater::onFocusReceived();
 }
+
+// Media stuff
+void LLFloaterTools::refreshMedia()
+{
+	getMediaState();	
+	LLFloaterMediaSettings::getInstance();
+	LLFloaterMediaSettings::initValues(mMediaSettings );
+}
+
+
+
+void LLFloaterTools::getMediaState()
+{
+	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+	
+	if( !objectp )
+	{
+		childSetEnabled("media_tex", FALSE);
+		childSetEnabled("add_media", FALSE);
+		childSetEnabled("delete_media", FALSE);
+		childSetEnabled("edit_media", FALSE);
+		updateMediaSettings();
+		return;
+	}
+	
+	bool editable = gAgent.isGodlike() || (objectp->permModify() && objectp->getPCode() == LL_PCODE_VOLUME);
+	
+	// Media settings
+	U8 has_media = (U8)0;
+	struct media_functor : public LLSelectedTEGetFunctor<U8>
+	{
+		U8 get(LLViewerObject* object, S32 face)
+		{
+			return (object->getTE(face)->getMediaTexGen());
+		}
+	} func;
+	bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, has_media );
+	
+	// update UI depending on whether "object" (prim or face) has media
+	// and whether or not you are allowed to edit it.
+	bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
+	childSetEnabled("media_tex",  bool_has_media & editable);
+	childSetEnabled( "edit_media", bool_has_media & editable );
+	childSetEnabled( "delete_media", bool_has_media & editable );
+	childSetEnabled( "add_media", ( ! bool_has_media ) & editable );
+	
+	// load values for media settings
+	updateMediaSettings();
+	
+	// if identical is set, all faces are same
+	if ( identical )
+	{
+		// TODO: display a list of all media on the face - use 'identical' flag
+	};
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLFloaterTools::onClickBtnAddMedia()
+{
+	// check for the edit tool and now many faces are selected
+	LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+	if((tool != LLToolFace::getInstance()) || LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+	{
+		LLNotifications::instance().add("MultipleFacesSelected",LLSD(), LLSD(), multipleFacesSelectedConfirm);
+		
+	}
+	else
+	{
+		onClickBtnEditMedia();
+	}
+
+}
+
+// static
+bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	switch( option )
+	{
+		case 0:  // "Yes"
+			gFloaterTools->onClickBtnEditMedia();
+			break;
+		case 1:  // "No"
+		default:
+			break;
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLFloaterTools::onClickBtnEditMedia()
+{
+	refreshMedia();
+	LLFloaterReg::showInstance("media_settings");	
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLFloaterTools::onClickBtnDeleteMedia()
+{
+	LLNotifications::instance().add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+
+// static
+bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	switch( option )
+	{
+		case 0:  // "Yes"
+			LLSelectMgr::getInstance()->selectionSetMedia( 0 );
+			if(LLFloaterReg::instanceVisible("media_settings"))
+			{
+				LLFloaterReg::hideInstance("media_settings");
+			}
+			break;
+			
+		case 1:  // "No"
+		default:
+			break;
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::updateMediaSettings()
+{
+    bool identical( false );
+    std::string base_key( "" );
+    std::string value_str( "" );
+    int value_int = 0;
+    bool value_bool = false;
+	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
+    // TODO: (CP) refactor this using something clever or boost or both !!
+
+    LLMediaEntry default_media_data;
+
+    // controls 
+    U8 value_u8 = default_media_data.getControls();
+    struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+    {
+        U8 get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getControls();
+            LLMediaEntry default_media_data;
+            return default_media_data.getControls();
+        };
+		
+    } func_controls;
+    identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
+    base_key = std::string( LLMediaEntry::CONTROLS_KEY );
+    mMediaSettings[ base_key ] = value_u8;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // First click (formerly left click)
+    value_bool = default_media_data.getFirstClickInteract();
+    struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getFirstClickInteract();
+            LLMediaEntry default_media_data;
+            return default_media_data.getFirstClickInteract();
+        };
+		
+    } func_first_click;
+    identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
+    base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Home URL
+    value_str = default_media_data.getHomeURL();
+    struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+    {
+        std::string get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getHomeURL();
+            LLMediaEntry default_media_data;
+            return default_media_data.getHomeURL();
+        };
+		
+    } func_home_url;
+    identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
+    base_key = std::string( LLMediaEntry::HOME_URL_KEY );
+    mMediaSettings[ base_key ] = value_str;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	llwarns<<"Angela debug : home url string == "<<value_str<<llendl;
+	
+    // Current URL
+    value_str = default_media_data.getCurrentURL();
+    struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+    {
+        std::string get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getCurrentURL();
+            LLMediaEntry default_media_data;
+            return default_media_data.getCurrentURL();
+        };
+		
+    } func_current_url;
+    identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
+    base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
+    mMediaSettings[ base_key ] = value_str;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Auto zoom
+    value_bool = default_media_data.getAutoZoom();
+    struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getAutoZoom();
+            LLMediaEntry default_media_data;
+            return default_media_data.getAutoZoom();
+        };
+		
+    } func_auto_zoom;
+    identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
+    base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Auto play
+    value_bool = default_media_data.getAutoPlay();
+    struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getAutoPlay();
+			LLMediaEntry default_media_data;
+            return default_media_data.getAutoPlay();
+        };
+		
+    } func_auto_play;
+    identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
+    base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Auto scale
+    value_bool = default_media_data.getAutoScale();
+    struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getAutoScale();
+			LLMediaEntry default_media_data;
+            return default_media_data.getAutoScale();;
+        };
+		
+    } func_auto_scale;
+    identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
+    base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Auto loop
+    value_bool = default_media_data.getAutoLoop();
+    struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getAutoLoop();
+			LLMediaEntry default_media_data;
+            return default_media_data.getAutoLoop();
+        };
+		
+    } func_auto_loop;
+    identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
+    base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // width pixels (if not auto scaled)
+    value_int = default_media_data.getWidthPixels();
+    struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+    {
+        int get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getWidthPixels();
+			LLMediaEntry default_media_data;
+            return default_media_data.getWidthPixels();
+        };
+		
+    } func_width_pixels;
+    identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
+    base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
+    mMediaSettings[ base_key ] = value_int;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // height pixels (if not auto scaled)
+    value_int = default_media_data.getHeightPixels();
+    struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+    {
+        int get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getHeightPixels();
+			LLMediaEntry default_media_data;
+            return default_media_data.getHeightPixels();
+        };
+		
+    } func_height_pixels;
+    identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
+    base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
+    mMediaSettings[ base_key ] = value_int;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Enable Alt image
+    value_bool = default_media_data.getAltImageEnable();
+    struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getAltImageEnable();
+			LLMediaEntry default_media_data;
+            return default_media_data.getAltImageEnable();
+        };
+		
+    } func_enable_alt_image;
+    identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
+    base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - owner interact
+    value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+    struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+        };
+		
+    } func_perms_owner_interact;
+    identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - owner control
+    value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
+    struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
+        };
+		
+    } func_perms_owner_control;
+    identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - group interact
+    value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+    struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+        };
+		
+    } func_perms_group_interact;
+    identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - group control
+    value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
+    struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
+        };
+		
+    } func_perms_group_control;
+    identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - anyone interact
+    value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+    struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+        };
+		
+    } func_perms_anyone_interact;
+    identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // Perms - anyone control
+    value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+    struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+			LLMediaEntry default_media_data;
+            return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+        };
+		
+    } func_perms_anyone_control;
+    identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
+    base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // security - whitelist enable
+    value_bool = default_media_data.getWhiteListEnable();
+    struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+    {
+        bool get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getWhiteListEnable();
+			LLMediaEntry default_media_data;
+            return default_media_data.getWhiteListEnable();
+        };
+		
+    } func_whitelist_enable;
+    identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
+    base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
+    mMediaSettings[ base_key ] = value_bool;
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+	
+    // security - whitelist URLs
+    std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+    struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+    {
+        std::vector<std::string> get( LLViewerObject* object, S32 face )
+        {
+            if ( object )
+                if ( object->getTE(face) )
+                    if ( object->getTE(face)->getMediaData() )
+                        return object->getTE(face)->getMediaData()->getWhiteList();
+            LLMediaEntry default_media_data;
+            return default_media_data.getWhiteList();
+        };
+		
+    } func_whitelist_urls;
+    identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
+    base_key = std::string( LLMediaEntry::WHITELIST_KEY );
+	mMediaSettings[ base_key ].clear();
+    std::vector< std::string >::iterator iter = value_vector_str.begin();
+    while( iter != value_vector_str.end() )
+    {
+        std::string white_list_url = *iter;
+        mMediaSettings[ base_key ].append( white_list_url );
+        ++iter;
+    };
+	
+    mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+}
+
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 1b9f1d31ec3229b1858491b6855637ccc1515fad..008c9677ed06dd1e81930797618afcd09320e64e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -100,13 +100,24 @@ class LLFloaterTools
 
 	void setStatusText(const std::string& text);
 	static void setEditTool(void* data);
+	void setTool(const LLSD& user_data);
 	void saveLastTool();
+	void onClickBtnDeleteMedia();
+	void onClickBtnAddMedia();
+	void onClickBtnEditMedia();
+	
+
 private:
 	void onClose();
 	void refresh();
-
+	void refreshMedia();
+	void getMediaState();
+	void updateMediaSettings();
+	void getMeidaState();
+	static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+	static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
 	static void setObjectType( LLPCode pcode );
-	static void onClickGridOptions(void* data);
+	void onClickGridOptions();
 
 public:
 	LLButton		*mBtnFocus;
@@ -175,6 +186,10 @@ class LLFloaterTools
 	BOOL					mDirty;
 
 	std::map<std::string, std::string> mStatusText;
+
+protected:
+	LLSD				mMediaSettings;
+	
 };
 
 extern LLFloaterTools *gFloaterTools;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 1e975cd4473c4ee3f1bf8782a639d2156128ba23..2b01a5637317da9d06bd4aed1edcc96b601a9314 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -35,6 +35,7 @@
 #include "llfloaterurlentry.h"
 
 #include "llpanellandmedia.h"
+#include "llpanelface.h"
 
 // project includes
 #include "llcombobox.h"
@@ -145,13 +146,23 @@ void LLFloaterURLEntry::buildURLHistory()
 
 void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
 {
-	LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
+	LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
 	if (panel_media)
 	{
 		// status is ignored for now -- error = "none/none"
 		panel_media->setMediaType(mime_type);
 		panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
 	}
+	else
+	{
+		LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
+		if(panel_face)
+		{
+			panel_face->setMediaType(mime_type);
+			panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
+		}
+
+	}
 	// Decrement the cursor
 	getWindow()->decBusyCount();
 	childSetVisible("loading_label", false);
@@ -159,29 +170,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
 }
 
 // static
-LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
+LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent, const std::string media_url)
 {
-	if (sInstance)
-	{
-		sInstance->openFloater();
-	}
-	else
+	if (!sInstance)
 	{
 		sInstance = new LLFloaterURLEntry(parent);
 	}
-	sInstance->updateFromLandMediaPanel();
+	sInstance->openFloater();
+	sInstance->addURLToCombobox(media_url);
 	return sInstance->getHandle();
 }
 
-void LLFloaterURLEntry::updateFromLandMediaPanel()
-{
-	LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
-	if (panel_media)
-	{
-		std::string media_url = panel_media->getMediaURL();
-		addURLToCombobox(media_url);
-	}
-}
+
 
 bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
 {
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 0aeca823b809958284a6d623695bba2dc171b85a..6dd9c8453c0d1835a446e292fd05a733744aaa62 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -44,10 +44,8 @@ class LLFloaterURLEntry : public LLFloater
 public:
 	// Can only be shown by LLPanelLandMedia, and pushes data back into
 	// that panel via the handle.
-	static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
+	static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
 	/*virtual*/	BOOL	postBuild();
-	void updateFromLandMediaPanel();
-
 	void headerFetchComplete(U32 status, const std::string& mime_type);
 
 	bool addURLToCombobox(const std::string& media_url);
diff --git a/indra/newview/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..551a5191fcd937dff383f91b0ccaeda714028c7e
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file llfloaterwhitelistentry.cpp
+ * @brief LLFloaterWhistListEntry class implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007-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 "llfloaterreg.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterwhitelistentry.h"
+#include "llpanelmediasettingssecurity.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "lllineeditor.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::LLFloaterWhiteListEntry( const LLSD& key ) :
+	LLFloater(key)
+{
+//	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterWhiteListEntry::postBuild()
+{
+	mWhiteListEdit = getChild<LLLineEditor>("whitelist_entry");
+
+	childSetAction("cancel_btn", onBtnCancel, this);
+	childSetAction("ok_btn", onBtnOK, this);
+
+	setDefaultBtn("ok_btn");
+
+	return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnOK( void* userdata )
+{
+	LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+
+	LLPanelMediaSettingsSecurity* panel = LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings")->getPanelSecurity();
+	if ( panel )
+	{
+		std::string white_list_item = self->mWhiteListEdit->getText();
+
+		panel->addWhiteListItem( white_list_item );
+	};
+	
+	self->closeFloater();	
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnCancel( void* userdata )
+{
+	LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+	
+	self->closeFloater();
+}
diff --git a/indra/newview/llfloaterwhitelistentry.h b/indra/newview/llfloaterwhitelistentry.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ab5fb78b9ea6812de1eb1c6137989843d18b533
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterwhitelistentry.h
+ * @brief LLFloaterWhiteListEntry class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007-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_LLFLOATERWHITELISTENTRY_H
+#define LL_LLFLOATERWHITELISTENTRY_H
+
+#include "llfloater.h"
+
+class LLLineEditor;
+
+class LLFloaterWhiteListEntry : 
+	public LLFloater
+{
+	public:
+		LLFloaterWhiteListEntry(const LLSD& key);
+		~LLFloaterWhiteListEntry();
+	
+		BOOL postBuild();
+
+	private:
+		LLLineEditor* mWhiteListEdit;
+
+		static void onBtnOK(void*);
+		static void onBtnCancel(void*);
+};
+
+#endif  // LL_LLFLOATERWHITELISTENTRY_H
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 2a29566120aa55467d4df999a03c374088b8b49a..d149c8bbb5549c8df645f00f2e56cf7de57e36dd 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1318,7 +1318,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		mRenamer->setVisible( TRUE );
 		// set focus will fail unless item is visible
 		mRenamer->setFocus( TRUE );
-		mRenamer->setTopLostCallback(onRenamerLost);
+		mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));
 		gFocusMgr.setTopCtrl( mRenamer );
 	}
 }
@@ -2147,7 +2147,7 @@ void LLFolderView::updateRenamerPosition()
 ///----------------------------------------------------------------------------
 
 //static 
-void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data)
+void LLFolderView::onRenamerLost( LLFocusableElement* renamer)
 {
 	LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer);
 	if (uictrl)
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index a05dec3193e52839884f9902da2efb89825be1f9..69c0c5b13231078982ae07c04d9654fc1b389922 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -279,7 +279,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	LLScrollContainer* mScrollContainer;  // NULL if this is not a child of a scroll container.
 
 	void commitRename( const LLSD& data );
-	static void onRenamerLost( LLFocusableElement* renamer, void* user_data);
+	static void onRenamerLost( LLFocusableElement* renamer);
 
 	void finishRenamingItem( void );
 	void closeRenamer( void );
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index d3b013237bae237d29c6e94cfae1e2704fa1d7e8..905857f393dd9ddfc4d40ec7cd4ced51eee71c11 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -73,7 +73,11 @@ LLGroupList::Params::Params()
 
 LLGroupList::LLGroupList(const Params& p)
 :	LLFlatListView(p)
+	, mDirty(true) // to force initial update
 {
+	// Listen for agent group changes.
+	gAgent.addListener(this, "new group");
+
 	mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
 	setCommitOnSelectionChange(true);
 	// TODO: implement context menu
@@ -84,17 +88,41 @@ LLGroupList::LLGroupList(const Params& p)
 	setComparator(&GROUP_COMPARATOR);
 }
 
+LLGroupList::~LLGroupList()
+{
+	gAgent.removeListener(this);
+}
+
+// virtual
+void LLGroupList::draw()
+{
+	if (mDirty)
+		refresh();
+
+	LLFlatListView::draw();
+}
+
+void LLGroupList::setNameFilter(const std::string& filter)
+{
+	if (mNameFilter != filter)
+	{
+		mNameFilter = filter;
+		setDirty();
+	}
+}
+
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
 {
     LLStringUtil::toUpper(haystack);
     return haystack.find(needle_upper) != std::string::npos;
 }
 
-BOOL LLGroupList::update(const std::string& name_filter)
+void LLGroupList::refresh()
 {
 	const LLUUID& 		highlight_id	= gAgent.getGroupID();
 	S32					count			= gAgent.mGroups.count();
 	LLUUID				id;
+	bool				have_filter		= !mNameFilter.empty();
 
 	clear();
 
@@ -102,7 +130,7 @@ BOOL LLGroupList::update(const std::string& name_filter)
 	{
 		id = gAgent.mGroups.get(i).mID;
 		const LLGroupData& group_data = gAgent.mGroups.get(i);
-		if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
+		if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
 			continue;
 		addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
 	}
@@ -113,13 +141,14 @@ BOOL LLGroupList::update(const std::string& name_filter)
 	// add "none" to list at top
 	{
 		std::string loc_none = LLTrans::getString("GroupsNone");
-		if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
+		if (have_filter || findInsensitive(loc_none, mNameFilter))
 			addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
 	}
 
 	selectItemByUUID(highlight_id);
 
-	return TRUE;
+	setDirty(false);
+	onCommit();
 }
 
 void LLGroupList::toggleIcons()
@@ -158,6 +187,18 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
 //	setCommentVisible(false);
 }
 
+// virtual
+bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	// Why is "new group" sufficient?
+	if (event->desc() == "new group")
+	{
+		setDirty();
+		return true;
+	}
+
+	return false;
+}
 
 /************************************************************************/
 /*          LLGroupListItem implementation                              */
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 7708b58de688b8472d7b9721c6d2755da0656351..9c3ab88901bd5312d4b7c0ca0687e8dcf829c792 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -33,10 +33,19 @@
 #ifndef LL_LLGROUPLIST_H
 #define LL_LLGROUPLIST_H
 
+#include "llevent.h"
 #include "llflatlistview.h"
 #include "llpanel.h"
+#include "llpointer.h"
 
-class LLGroupList: public LLFlatListView
+/**
+ * Auto-updating list of agent groups.
+ * 
+ * Can use optional group name filter.
+ * 
+ * @see setNameFilter()
+ */
+class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
 {
 	LOG_CLASS(LLGroupList);
 public:
@@ -46,14 +55,23 @@ class LLGroupList: public LLFlatListView
 	};
 
 	LLGroupList(const Params& p);
-	BOOL update(const std::string& name_filter = LLStringUtil::null);
+	virtual ~LLGroupList();
+
+	virtual void draw(); // from LLView
+
+	void setNameFilter(const std::string& filter);
 	void toggleIcons();
 	bool getIconsVisible() const { return mShowIcons; }
-
+	
 private:
+	void setDirty(bool val = true)		{ mDirty = val; }
+	void refresh();
 	void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+	bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
 
 	bool mShowIcons;
+	bool mDirty;
+	std::string mNameFilter;
 };
 
 class LLButton;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 29102feb64dcdcb90c50b690b0b92c9ed82ebe45..d0be581f6df1d8179e764d2f9f5994d35533fdb3 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -48,6 +48,7 @@
 #include "lltrans.h"
 #include "llviewertexteditor.h"
 #include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
 
 
 
@@ -62,33 +63,44 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mInputEditor(NULL), 
 	mPositioned(false)
 {
-	LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
-	if(session)
+	EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
+	if(IM_COUNT != type)
 	{
-		mDialog = session->mType;
-	}
+		mDialog = type;
 
-	if (mDialog == IM_NOTHING_SPECIAL)
-	{
-		mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
-	}
-	else
-	{
-		mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+		if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog)
+		{
+			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
+		}
+		else
+		{
+			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+		}
 	}
-// 	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
-
-	gFocusMgr.addFocusChangeCallback(boost::bind(&LLIMFloater::focusChangeCallback, this));
 
 	mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this));
+
+	LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
 }
 
 void LLIMFloater::onClose()
 {
 	LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
+
+	//*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
 	gIMMgr->removeSession(mSessionID);
 }
 
+void LLIMFloater::setMinimized(BOOL minimize)
+{
+	if(!isDocked())
+	{
+		setVisible(!minimize);
+	}	
+
+	LLFloater::setMinimized(minimize);
+}
+
 /* static */
 void LLIMFloater::newIMCallback(const LLSD& data){
 	
@@ -152,16 +164,17 @@ void LLIMFloater::sendMsg()
 
 LLIMFloater::~LLIMFloater()
 {
+	LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
 }
 
 //virtual
 BOOL LLIMFloater::postBuild()
 {
-	LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
-	if(session)
+	const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+	if (other_party_id.notNull())
 	{
-		mOtherParticipantUUID = session->mOtherParticipantID;
-		mControlPanel->setID(session->mOtherParticipantID);
+		mOtherParticipantUUID = other_party_id;
+		mControlPanel->setID(mOtherParticipantUUID);
 	}
 
 	LLButton* slide_left = getChild<LLButton>("slide_left_btn");
@@ -177,8 +190,8 @@ BOOL LLIMFloater::postBuild()
 	// enable line history support for instant message bar
 	mInputEditor->setEnableLineHistory(TRUE);
 	
-	mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
-	mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
 	mInputEditor->setCommitOnFocusLost( FALSE );
 	mInputEditor->setRevertOnEsc( FALSE );
@@ -216,17 +229,6 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
 	return self->mControlPanel;
 }
 
-
-
-void LLIMFloater::focusChangeCallback()
-{
-	// hide docked floater if user clicked inside in-world area
-	if (isDocked() && gFocusMgr.getKeyboardFocus() == NULL)
-	{
-		setVisible(false);
-	}
-}
-
 void LLIMFloater::onSlide()
 {
 	LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
@@ -271,13 +273,13 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 		}
 
 		floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
-				LLDockControl::TOP,  boost::bind(&LLIMFloater::getEnabledRect, floater, _1)));
+				LLDockControl::TOP,  boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
 	}
 
 	return floater;
 }
 
-void LLIMFloater::getEnabledRect(LLRect& rect)
+void LLIMFloater::getAllowedRect(LLRect& rect)
 {
 	rect = gViewerWindow->getWorldViewRect();
 }
@@ -285,8 +287,10 @@ void LLIMFloater::getEnabledRect(LLRect& rect)
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
 	// update notification channel state
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+	LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+	
 	LLDockableFloater::setDocked(docked, pop_on_undock);
 
 	// update notification channel state
@@ -298,8 +302,9 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 
 void LLIMFloater::setVisible(BOOL visible)
 {
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+	LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
 	LLDockableFloater::setVisible(visible);
 
 	// update notification channel state
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 276f38e82969c0ee9893d48606411e0a298f8ffc..a183212f041bf8a7a2ae9a7ec04df0be3ad35b67 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -57,6 +57,8 @@ class LLIMFloater : public LLDockableFloater
 
 	// LLFloater overrides
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+	// override LLFloater's minimization according to EXT-1216
+	/*virtual*/ void setMinimized(BOOL minimize);
 
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
@@ -90,8 +92,8 @@ class LLIMFloater : public LLDockableFloater
 	void			onSlide();
 	static void*	createPanelIMControl(void* userdata);
 	static void*	createPanelGroupControl(void* userdata);
-	void focusChangeCallback();
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 	
 	LLPanelChatControlPanel* mControlPanel;
 	LLUUID mSessionID;
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 46067c081f60a07de037512e55548c9982f567e7..74971f3fd85d101a345575f2563776e2be1fb654 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -109,7 +109,9 @@ bool LLIMHandler::processNotification(const LLSD& notify)
 		p.panel = im_box;
 		p.can_be_stored = false;
 		p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager;
 		mNewNotificationSignal();
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index de4faf72f504200f58ab4cc4f6b3f5a4a63e0190..abd3cd4def2657b3b0cacc3a084f28f5a556f1de 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -940,7 +940,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	mHistoryEditor(NULL),
 	mSessionUUID(session_id),
 	mSessionLabel(session_label),
-	mVoiceChannel(NULL),
 	mSessionInitialized(FALSE),
 	mSessionStartMsgPos(0),
 	mOtherParticipantUUID(other_participant_id),
@@ -956,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	mTextIMPossible(TRUE),
 	mProfileButtonEnabled(TRUE),
 	mCallBackEnabled(TRUE),
-	mSpeakers(NULL),
 	mSpeakerPanel(NULL),
 	mFirstKeystrokeTimer(),
 	mLastKeystrokeTimer()
@@ -967,7 +965,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	case IM_SESSION_GROUP_START:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
 		xml_filename = "floater_instant_message_group.xml";
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	case IM_SESSION_INVITE:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
@@ -979,16 +976,13 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		{
 			xml_filename = "floater_instant_message_ad_hoc.xml";
 		}
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	case IM_SESSION_P2P_INVITE:
 		xml_filename = "floater_instant_message.xml";
-		mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
 		break;
 	case IM_SESSION_CONFERENCE_START:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
 		xml_filename = "floater_instant_message_ad_hoc.xml";
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	// just received text from another user
 	case IM_NOTHING_SPECIAL:
@@ -998,8 +992,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
 		mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
 		mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
-		
-		mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
 		break;
 	default:
 		llwarns << "Unknown session type" << llendl;
@@ -1007,10 +999,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		break;
 	}
 
-	mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
-	// All participants will be added to the list of people we've recently interacted with.
-	mSpeakers->addListener(&LLRecentPeople::instance(), "add");
-
 	LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
 
 	setTitle(mSessionLabel);
@@ -1058,38 +1046,8 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 
 LLFloaterIMPanel::~LLFloaterIMPanel()
 {
-	delete mSpeakers;
-	mSpeakers = NULL;
-	
-	// End the text IM session if necessary
-	if(gVoiceClient && mOtherParticipantUUID.notNull())
-	{
-		switch(mDialog)
-		{
-			case IM_NOTHING_SPECIAL:
-			case IM_SESSION_P2P_INVITE:
-				gVoiceClient->endUserIMSession(mOtherParticipantUUID);
-			break;
-			
-			default:
-				// Appease the compiler
-			break;
-		}
-	}
-	
-	//kicks you out of the voice channel if it is currently active
-
-	// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
-	mVoiceChannel->deactivate();
-	
-	delete mVoiceChannel;
-	mVoiceChannel = NULL;
-
 	//delete focus lost callback
-	if(mInputEditor)
-	{
-		mInputEditor->setFocusLostCallback( NULL );
-	}
+	mFocusCallbackConnection.disconnect();
 }
 
 BOOL LLFloaterIMPanel::postBuild() 
@@ -1099,8 +1057,8 @@ BOOL LLFloaterIMPanel::postBuild()
 	mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2));
 	
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
-	mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
-	mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+	mFocusCallbackConnection = mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this));
 	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
 	mInputEditor->setCommitCallback( onCommitChat, this );
 	mInputEditor->setCommitOnFocusLost( FALSE );
@@ -1155,7 +1113,8 @@ BOOL LLFloaterIMPanel::postBuild()
 void* LLFloaterIMPanel::createSpeakersPanel(void* data)
 {
 	LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
-	floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID);
+	floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE);
 	return floaterp->mSpeakerPanel;
 }
 
@@ -1201,12 +1160,14 @@ void LLFloaterIMPanel::draw()
 					  && mCallBackEnabled;
 
 	// hide/show start call and end call buttons
-	childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
-	childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+	childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
+	childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
 	childSetEnabled("start_call_btn", enable_connect);
 	childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
 	
-	LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
+	LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID());
 	if(!mTextIMPossible)
 	{
 		mInputEditor->setEnabled(FALSE);
@@ -1230,7 +1191,7 @@ void LLFloaterIMPanel::draw()
 	}
 
 	// show speakers window when voice first connects
-	if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
+	if (mShowSpeakersOnConnect && voice_channel->isActive())
 	{
 		childSetVisible("active_speakers_panel", TRUE);
 		mShowSpeakersOnConnect = FALSE;
@@ -1266,11 +1227,11 @@ void LLFloaterIMPanel::draw()
 	else
 	{
 		// refresh volume and mute checkbox
-		childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+		childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
 		childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
 
 		childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
-		childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+		childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
 	}
 	LLFloater::draw();
 }
@@ -1406,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
 	{
 		mNumUnreadMessages++;
 	}
-
-	if (source != LLUUID::null)
-	{
-		mSpeakers->speakerChatted(source);
-		mSpeakers->setSpeakerTyping(source, FALSE);
-	}
 }
 
 
@@ -1592,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
 {
 	LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
 
-	self->mVoiceChannel->activate();
+	LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
 }
 
 // static
@@ -1600,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
 {
 	LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
 
-	self->getVoiceChannel()->deactivate();
+	LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
 }
 
 // static
@@ -1674,7 +1629,8 @@ void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
 		mNumUnreadMessages = 0;
 	}
 	
-	if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+	if (new_visibility.asBoolean() && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
 		LLFloaterReg::showInstance("voice_call", mSessionUUID);
 	else
 		LLFloaterReg::hideInstance("voice_call", mSessionUUID);
@@ -1726,11 +1682,6 @@ void LLFloaterIMPanel::sendMsg()
 	mSentTypingState = TRUE;
 }
 
-void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
-{
-	mSpeakers->updateSpeakers(speaker_updates); 
-}
-
 void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
 {
 	if (
@@ -1754,15 +1705,9 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
 	}
 }
 
-void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
-{
-	mSpeakers->setSpeakers(speaker_list);
-}
-
 void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
 {
 	mSessionUUID = session_id;
-	mVoiceChannel->updateSessionID(session_id);
 	mSessionInitialized = TRUE;
 
 	//we assume the history editor hasn't moved at all since
@@ -1793,6 +1738,7 @@ void LLFloaterIMPanel::requestAutoConnect()
 
 void LLFloaterIMPanel::setTyping(BOOL typing)
 {
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
 	if (typing)
 	{
 		// Every time you type something, reset this timer
@@ -1807,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
 			mSentTypingState = FALSE;
 		}
 
-		mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
+		speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
 	}
 	else
 	{
@@ -1817,7 +1763,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
 			sendTypingState(FALSE);
 			mSentTypingState = TRUE;
 		}
-		mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
+		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
 	}
 
 	mTyping = typing;
@@ -1877,7 +1823,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
 		mHistoryEditor->removeTextFromEnd(chars_to_remove);
 		if (im_info)
 		{
-			mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
+			LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE);
 		}
 	}
 }
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index dbf5e1cb6aba1f0657f592e13da0de046ee156d6..fb9b28ad16b791ed58721def9d36e57529ffe428 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -33,6 +33,7 @@
 #ifndef LL_IMPANEL_H
 #define LL_IMPANEL_H
 
+#include "llimview.h" //for LLIMModel
 #include "lldockablefloater.h"
 #include "lllogchat.h"
 #include "lluuid.h"
@@ -245,11 +246,7 @@ class LLFloaterIMPanel : public LLFloater
 
 	const LLUUID& getSessionID() const { return mSessionUUID; }
 	const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
-	LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
-	void updateSpeakersList(const LLSD& speaker_updates);
 	void processSessionUpdate(const LLSD& update);
-	void setSpeakers(const LLSD& speaker_list);
-	LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
 	EInstantMessage getDialogType() const { return mDialog; }
 	void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
 
@@ -305,7 +302,6 @@ class LLFloaterIMPanel : public LLFloater
 	LLUUID mSessionUUID;
 
 	std::string mSessionLabel;
-	LLVoiceChannel*	mVoiceChannel;
 
 	BOOL mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
@@ -346,7 +342,6 @@ class LLFloaterIMPanel : public LLFloater
 	BOOL mProfileButtonEnabled;
 	BOOL mCallBackEnabled;
 
-	LLIMSpeakerMgr* mSpeakers;
 	LLPanelActiveSpeakers* mSpeakerPanel;
 	
 	// Optimization:  Don't send "User is typing..." until the
@@ -357,6 +352,8 @@ class LLFloaterIMPanel : public LLFloater
 	// Timer to detect when user has stopped typing.
 	LLFrameTimer mLastKeystrokeTimer;
 
+	boost::signals2::connection mFocusCallbackConnection;
+
 	void disableWhileSessionStarting();
 };
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3cf78f957b3aabf921900b153a8602af7204b371..556eb5ffd70368bd567ecb6e5f5f01f8842aed8d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -114,10 +114,84 @@ void toast_callback(const LLSD& msg){
 
 LLIMModel::LLIMModel() 
 {
-	addChangedCallback(toast_callback);
 	addChangedCallback(LLIMFloater::newIMCallback);
+	addChangedCallback(toast_callback);
+}
+
+
+LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id )
+:	mSessionID(session_id),
+	mName(name),
+	mType(type),
+	mNumUnread(0),
+	mOtherParticipantID(other_participant_id),
+	mVoiceChannel(NULL),
+	mSpeakers(NULL)
+{
+	if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
+	{
+		mVoiceChannel  = new LLVoiceChannelP2P(session_id, name, other_participant_id);
+	}
+	else
+	{
+		mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
+	}
+	mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+
+	// All participants will be added to the list of people we've recently interacted with.
+	mSpeakers->addListener(&LLRecentPeople::instance(), "add");
+}
+
+LLIMModel::LLIMSession::~LLIMSession()
+{
+	delete mSpeakers;
+	mSpeakers = NULL;
+
+	// End the text IM session if necessary
+	if(gVoiceClient && mOtherParticipantID.notNull())
+	{
+		switch(mType)
+		{
+		case IM_NOTHING_SPECIAL:
+		case IM_SESSION_P2P_INVITE:
+			gVoiceClient->endUserIMSession(mOtherParticipantID);
+			break;
+
+		default:
+			// Appease the linux compiler
+			break;
+		}
+	}
+
+	// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
+	mVoiceChannel->deactivate();
+	
+	delete mVoiceChannel;
+	mVoiceChannel = NULL;
 }
 
+LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
+{
+	return get_if_there(LLIMModel::instance().sSessionsMap, session_id,
+		(LLIMModel::LLIMSession*) NULL);
+}
+
+void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+	if (new_session_id == old_session_id) return;
+
+	LLIMSession* session = findIMSession(old_session_id);
+	if (session)
+	{
+		session->mSessionID = new_session_id;
+		session->mVoiceChannel->updateSessionID(new_session_id);
+
+		//*TODO set session initialized flag here? (IB)
+
+		sSessionsMap.erase(old_session_id);
+		sSessionsMap[new_session_id] = session;
+	}
+}
 
 void LLIMModel::testMessages()
 {
@@ -153,7 +227,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
 		return false;
 	}
 
-	LLIMSession* session = new LLIMSession(name, type, other_participant_id);
+	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id);
 	sSessionsMap[session_id] = session;
 
 	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
@@ -170,12 +244,12 @@ bool LLIMModel::clearSession(LLUUID session_id)
 	return true;
 }
 
+//*TODO remake it, instead of returing the list pass it as as parameter (IB)
 std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
 {
 	std::list<LLSD> return_list;
 
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
-
+	LLIMSession* session = findIMSession(session_id);
 	if (!session) 
 	{
 		llwarns << "session " << session_id << "does not exist " << llendl;
@@ -202,13 +276,14 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
 	mChangedSignal(arg);
 
     // TODO: in the future is there a more efficient way to return these
+	//of course there is - return as parameter (IB)
 	return return_list;
 
 }
 
 bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) { 
 	
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -231,7 +306,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut
 		
 bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { 
 
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -260,9 +335,9 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
 }
 
 
-const std::string& LLIMModel::getName(LLUUID session_id)
+const std::string& LLIMModel::getName(const LLUUID& session_id) const
 {
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -273,6 +348,66 @@ const std::string& LLIMModel::getName(LLUUID session_id)
 	return session->mName;
 }
 
+const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return -1;
+	}
+
+	return session->mNumUnread;
+}
+
+const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return LLUUID::null;
+	}
+
+	return session->mOtherParticipantID;
+}
+
+EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return IM_COUNT;
+	}
+
+	return session->mType;
+}
+
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return NULL;
+	}
+
+	return session->mVoiceChannel;
+}
+
+LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return NULL;
+	}
+
+	return session->mSpeakers;
+}
+
 
 // TODO get rid of other participant ID
 void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) 
@@ -316,7 +451,7 @@ void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
 }
 
 
-
+//*TODO update list of messages in a LLIMSession (IB)
 void LLIMModel::sendMessage(const std::string& utf8_text,
 					 const LLUUID& im_session_id,
 					 const LLUUID& other_participant_id,
@@ -415,9 +550,16 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 		LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
 		if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
 
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
+		if (speaker_mgr)
+		{
+			speaker_mgr->speakerChatted(gAgentID);
+			speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+		}
 	}
 
 	// Add the recipient to the recent people list.
+	//*TODO should be deleted, because speaker manager updates through callback the recent list
 	LLRecentPeople::instance().add(other_participant_id);
 }
 										  
@@ -633,10 +775,8 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 	{
 		if ( gIMMgr)
 		{
-			LLFloaterIMPanel* floaterp =
-				gIMMgr->findFloaterBySession(mSessionID);
-
-			if (floaterp)
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			if (speaker_mgr)
 			{
 				//we've accepted our invitation
 				//and received a list of agents that were
@@ -650,15 +790,20 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 				//but unfortunately, our base that we are receiving here
 				//may not be the most up to date.  It was accurate at
 				//some point in time though.
-				floaterp->setSpeakers(content);
+				speaker_mgr->setSpeakers(content);
 
 				//we now have our base of users in the session
 				//that was accurate at some point, but maybe not now
 				//so now we apply all of the udpates we've received
 				//in case of race conditions
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(mSessionID));
+				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+			}
+			
+			LLFloaterIMPanel* floaterp =
+				gIMMgr->findFloaterBySession(mSessionID);
 
+			if (floaterp)
+			{
 				if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
 				{
 					floaterp->requestAutoConnect();
@@ -1104,6 +1249,12 @@ void LLIMMgr::addMessage(
 		//no session ID...compute new one
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
+
+	if (!LLIMModel::getInstance()->findIMSession(new_session_id))
+	{
+		LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id);
+	}
+
 	floater = findFloaterBySession(new_session_id);
 	if (!floater)
 	{
@@ -1169,6 +1320,14 @@ void LLIMMgr::addMessage(
 	else
 	{
 		floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
+
+		//*TODO consider moving that speaker management stuff into model (IB)
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(new_session_id);
+		if (speaker_mgr)
+		{
+			speaker_mgr->speakerChatted(gAgentID);
+			speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+		}
 	}
 
 	LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
@@ -1273,11 +1432,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
 {
 	LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
 
-	LLFloaterIMPanel* floater = findFloaterBySession(session_id);
-	if(floater)
+	LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id);
+	if (voice_channel)
 	{
-		LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
-		voice_channelp->setSessionHandle(voice_session_handle, caller_uri);		
+		voice_channel->setSessionHandle(voice_session_handle, caller_uri);
 	}
 
 	return session_id;
@@ -1312,6 +1470,11 @@ LLUUID LLIMMgr::addSession(
 
 	LLUUID session_id = computeSessionID(dialog,other_participant_id);
 
+	if (!LLIMModel::getInstance()->findIMSession(session_id))
+	{
+		LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id);
+	}
+
 	LLFloaterIMPanel* floater = findFloaterBySession(session_id);
 	if(!floater)
 	{
@@ -1335,17 +1498,10 @@ LLUUID LLIMMgr::addSession(
 			noteMutedUsers(floater, ids);
 		}
 	}
-	else
-	{
-		// *TODO: Remove this?  Otherwise old communicate window opens on
-		// second initiation of IM session from People panel?
-		// floater->openFloater();
-	}
-	//mTabContainer->selectTabPanel(panel);
 	floater->setInputFocus(TRUE);
 	LLIMFloater::show(session_id);
-	notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
-	return floater->getSessionID();
+
+	return session_id;
 }
 
 // This removes the panel referenced by the uuid, and then restores
@@ -1705,7 +1861,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
 	LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
 	LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
 	mFloaters.insert(floater->getHandle());
-	LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
 	return floater;
 }
 
@@ -1825,24 +1980,25 @@ class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
 			gIMMgr->updateFloaterSessionID(
 				temp_session_id,
 				session_id);
+
+			LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id);
+
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+			if (speaker_mgr)
+			{
+				speaker_mgr->setSpeakers(body);
+				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+			}
+
 			LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
 			if (floaterp)
 			{
-				floaterp->setSpeakers(body);
-
-				//apply updates we've possibly received previously
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(session_id));
-
 				if ( body.has("session_info") )
 				{
 					floaterp->processSessionUpdate(body["session_info"]);
 				}
-
-				//aply updates we've possibly received previously
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(session_id));
 			}
+
 			gIMMgr->clearPendingAgentListUpdates(session_id);
 		}
 		else
@@ -1932,15 +2088,15 @@ class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
 		const LLSD& context,
 		const LLSD& input) const
 	{
-		LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
-		if (floaterp)
+		const LLUUID& session_id = input["body"]["session_id"].asUUID();
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+		if (speaker_mgr)
 		{
-			floaterp->updateSpeakersList(
-				input["body"]);
+			speaker_mgr->updateSpeakers(input["body"]);
 		}
 		else
 		{
-			//we don't have a floater yet..something went wrong
+			//we don't have a speaker manager yet..something went wrong
 			//we are probably receiving an update here before
 			//a start or an acceptance of an invitation.  Race condition.
 			gIMMgr->addPendingAgentListUpdates(
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 219af0705d8eb192cd8961815985450e051c1345..9a94d01bb29ee55de40bcf29a076790dab0389e3 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,8 @@
 #define LL_LLIMVIEW_H
 
 #include "lldarray.h"
+#include "llfloateractivespeakers.h" //for LLIMSpeakerMgr
+#include "llimpanel.h" //for voice channels
 #include "llmodaldialog.h"
 #include "llinstantmessage.h"
 #include "lluuid.h"
@@ -50,21 +52,40 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 
 	struct LLIMSession
 	{
-		LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) 
-			:mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
-		
+		LLIMSession(const LLUUID& session_id, const std::string& name, 
+			const EInstantMessage& type, const LLUUID& other_participant_id);
+		virtual ~LLIMSession();
+
+		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
 		LLUUID mOtherParticipantID;
 		S32 mNumUnread;
 		std::list<LLSD> mMsgs;
+
+		LLVoiceChannel* mVoiceChannel;
+		LLIMSpeakerMgr* mSpeakers;
 	};
 	
 
 	LLIMModel();
 
+	//*TODO make it non-static as LLIMMOdel is a singleton (IB)
 	static std::map<LLUUID, LLIMSession*> sSessionsMap;  //mapping session_id to session
+
 	boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+	
+	/** 
+	 * Find an IM Session corresponding to session_id
+	 * Returns NULL if the session does not exist
+	 */
+	LLIMSession* findIMSession(const LLUUID& session_id) const;
+
+	/**
+	 * Rebind session data to a new session id.
+	 */
+	void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
 	boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
 
 	bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
@@ -72,10 +93,42 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
 	bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
 	bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); 
-    //used to get the name of the session, for use as the title
-    //currently just the other avatar name
-	const std::string& getName(LLUUID session_id);
-	
+	//used to get the name of the session, for use as the title
+	//currently just the other avatar name
+	const std::string& getName(const LLUUID& session_id) const;
+
+	/** 
+	 * Get number of unread messages in a session with session_id
+	 * Returns -1 if the session with session_id doesn't exist
+	 */
+	const S32 getNumUnread(const LLUUID& session_id) const;
+
+	/**
+	 * Get uuid of other participant in a session with session_id
+	 * Returns LLUUID::null if the session doesn't exist
+	 *
+ 	 * *TODO what to do with other participants in ad-hoc and group chats?
+	 */
+	const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
+
+	/**
+	 * Get type of a session specified by session_id
+	 * Returns EInstantMessage::IM_COUNT if the session does not exist
+	 */
+	EInstantMessage getType(const LLUUID& session_id) const;
+
+	/**
+	 * Get voice channel for the session specified by session_id
+	 * Returns NULL if the session does not exist
+	 */
+	LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
+
+	/**
+	* Get im speaker manager for the session specified by session_id
+	* Returns NULL if the session does not exist
+	*/
+	LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
+
 	static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
 	static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
 						  const std::vector<LLUUID>& ids, EInstantMessage dialog);
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 2ad83c76b510d20c806a928b1f83bcff54ec26f0..0542199fc1d939c09a64aed33a9d9b9da6988615 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -53,10 +53,15 @@
 #include "llagentui.h"
 
 
-class LLFetchlLandmarkByAgentPos : public LLInventoryCollectFunctor
+class LLFetchlLandmarkByPos : public LLInventoryCollectFunctor
 {
-	
+private:
+	LLVector3d mPos;
 public:
+	LLFetchlLandmarkByPos(const LLVector3d& pos) :
+		mPos(pos)
+	{}
+
 	/*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
 	{
 		if (!item || item->getType() != LLAssetType::AT_LANDMARK)
@@ -69,11 +74,10 @@ class LLFetchlLandmarkByAgentPos : public LLInventoryCollectFunctor
 		LLVector3d landmark_global_pos;
 		if (!landmark->getGlobalPos(landmark_global_pos))
 			return false;
-		LLVector3d a_pos = gAgent.getPositionGlobal();
 		//we have to round off each coordinates to compare positions properly
-		return llround(a_pos.mdV[VX]) ==  llround(landmark_global_pos.mdV[VX])
-				&& llround(a_pos.mdV[VY]) ==  llround(landmark_global_pos.mdV[VY])
-				&& llround(a_pos.mdV[VZ]) ==  llround(landmark_global_pos.mdV[VZ]);
+		return llround(mPos.mdV[VX]) ==  llround(landmark_global_pos.mdV[VX])
+				&& llround(mPos.mdV[VY]) ==  llround(landmark_global_pos.mdV[VY])
+				&& llround(mPos.mdV[VZ]) ==  llround(landmark_global_pos.mdV[VZ]);
 	}
 };
 
@@ -147,12 +151,12 @@ bool LLLandmarkActions::landmarkAlreadyExists()
 }
 
 
-LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForGlobalPos(const LLVector3d &pos)
 {
 	// Determine whether there are landmarks pointing to the current parcel.
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
-	LLFetchlLandmarkByAgentPos is_current_pos_landmark;
+	LLFetchlLandmarkByPos is_current_pos_landmark(pos);
 	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
 		cats,
 		items,
@@ -167,6 +171,11 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
 	return items[0];
 }
 
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
+{
+	return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
+}
+
 bool LLLandmarkActions::canCreateLandmarkHere()
 {
 	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index ce3ed76090bd617a47a982abbafeeb1c1278d801..ab8cc4d6a57266a25ae0556a315c1f880eb2f01f 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -52,6 +52,14 @@ class LLLandmarkActions
 	 */
 	static bool landmarkAlreadyExists();
 
+	/**
+	 * @brief Searches landmark for global position.
+	 * @return Returns landmark or NULL.
+	 * 
+	 * *TODO: dzaporozhan: There can be many landmarks for single parcel.
+	 */
+	static LLViewerInventoryItem* findLandmarkForGlobalPos(const LLVector3d &pos);
+
 	/**
 	 * @brief Searches landmark for agent global position.
 	 * @return Returns landmark or NULL.
@@ -60,6 +68,7 @@ class LLLandmarkActions
 	 */
 	static LLViewerInventoryItem* findLandmarkForAgentPos();
 
+
 	/**
 	 * @brief Checks whether agent has rights to create landmark for current parcel.
 	 */
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 9d14a3fbdcb9ea3527053e0ef82ea912fc6588b1..68dc3854dbf075ef80cdab609850d5891ca53e71 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -190,7 +190,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
 	params.max_length_bytes(p.max_chars);
 	params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
 	params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
-	params.focus_lost_callback(NULL);
 	params.handle_edit_keys_directly(true);
 	params.commit_on_focus_lost(false);
 	params.follows.flags(FOLLOWS_ALL);
@@ -657,8 +656,9 @@ void LLLocationInputCtrl::changeLocationPresentation()
 {
 	//change location presentation only if user does not  select anything and 
 	//human-readable region name  is being displayed
-	if(mTextEntry && !mTextEntry->hasSelection() && 
-		!LLSLURL::isSLURL(mTextEntry->getText()))
+	std::string text = mTextEntry->getText();
+	LLStringUtil::trim(text);
+	if(mTextEntry && !mTextEntry->hasSelection() && !LLSLURL::isSLURL(text))
 	{
 		//needs unescaped one
 		mTextEntry->setText(LLAgentUI::buildSLURL(false));
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 09a7edaa434c3fa4a949e82362dda2f0d8c3922e..b996c15a7d725858da724ef7ed5a37ed0bbdc000 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -36,7 +36,6 @@
 #include "llmediactrl.h"
 
 // viewer includes
-#include "llfloaterhtml.h"
 #include "llfloaterworldmap.h"
 #include "lluictrlfactory.h"
 #include "llurldispatcher.h"
@@ -44,6 +43,7 @@
 #include "llviewborder.h"
 #include "llviewercontrol.h"
 #include "llviewermedia.h"
+#include "llviewertexture.h"
 #include "llviewerwindow.h"
 #include "llnotifications.h"
 #include "llweb.h"
@@ -64,6 +64,9 @@ LLMediaCtrl::Params::Params()
 	border_visible("border_visible", true),
 	ignore_ui_scale("ignore_ui_scale", true),
 	hide_loading("hide_loading", false),
+	decouple_texture_size("decouple_texture_size", false),
+	texture_width("texture_width", 1024),
+	texture_height("texture_height", 1024),
 	caret_color("caret_color")
 {}
 
@@ -83,10 +86,12 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 	mMediaSource( 0 ),
 	mTakeFocusOnClick( true ),
 	mCurrentNavUrl( "" ),
-	mLastSetCursor( UI_CURSOR_ARROW ),
 	mStretchToFill( true ),
 	mMaintainAspectRatio ( true ),
-	mHideLoading (false)
+	mHideLoading (false),
+	mDecoupleTextureSize ( false ),
+	mTextureWidth ( 1024 ),
+	mTextureHeight ( 1024 )
 {
 	{
 		LLColor4 color = p.caret_color().get();
@@ -100,24 +105,29 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 	setBorderVisible(p.border_visible());
 	
 	mHideLoading = p.hide_loading();
+	
+	setDecoupleTextureSize(p.decouple_texture_size());
+	
+	setTextureSize(p.texture_width(), p.texture_height());
 
-	S32 screen_width = mIgnoreUIScale ? 
-		llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
-	S32 screen_height = mIgnoreUIScale ? 
-		llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
+	if(!getDecoupleTextureSize())
+	{
+		S32 screen_width = mIgnoreUIScale ? 
+			llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
+		S32 screen_height = mIgnoreUIScale ? 
+			llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
+			
+		setTextureSize(screen_width, screen_height);
+	}
 	
 	mMediaTextureID.generate();
-	mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, mMediaTextureID, screen_width, screen_height, false, false, "text/html");
-	if ( !mMediaSource )
+	
+	// We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.
+	if(!mHomePageUrl.empty())
 	{
-		llwarns << "media source create failed " << llendl;
-		// return;
+		navigateHome();
 	}
-
-	mMediaSource->setVisible( getVisible() );
-
-	mMediaSource->addObserver( this );
-	
+		
 	// FIXME: How do we create a bevel now?
 //	LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
 //	mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN );
@@ -180,9 +190,10 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
 	convertInputCoords(x, y);
 
 	if (mMediaSource)
+	{
 		mMediaSource->mouseMove(x, y);
-
-	gViewerWindow->setCursor(mLastSetCursor);
+		gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
+	}
 
 	return TRUE;
 }
@@ -390,19 +401,19 @@ void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility )
 //
 void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
 {
-	S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
-	S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
-	
-//	llinfos << "reshape called with width = " << width << ", height = " << height << llendl;
-	
-	// when floater is minimized, these sizes are negative
-	if ( screen_height > 0 && screen_width > 0 )
+	if(!getDecoupleTextureSize())
 	{
-		mMediaSource->setSize(screen_width, screen_height);
-		mForceUpdate = true;
-	}
+		S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
+		S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
 
-	LLPanel::reshape( width, height, called_from_parent );
+		// when floater is minimized, these sizes are negative
+		if ( screen_height > 0 && screen_width > 0 )
+		{
+			setTextureSize(screen_width, screen_height);
+		}
+	}
+	
+	LLUICtrl::reshape( width, height, called_from_parent );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -476,9 +487,10 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
 		return;
 	}
 	
-	if (mMediaSource)
+	if (ensureMediaSourceExists())
 	{
 		mCurrentNavUrl = url_in;
+		mMediaSource->setSize(mTextureWidth, mTextureHeight);
 		mMediaSource->navigateTo(url_in, mime_type, mime_type.empty());
 	}
 }
@@ -514,9 +526,10 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
 			return;
 		}
 	}
-	if (mMediaSource)
+	if (ensureMediaSourceExists())
 	{
 		mCurrentNavUrl = expanded_filename;
+		mMediaSource->setSize(mTextureWidth, mTextureHeight);
 		mMediaSource->navigateTo(expanded_filename, "text/html", false);
 	}
 
@@ -526,11 +539,11 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
 //
 void LLMediaCtrl::navigateHome()
 {
-	if( mHomePageUrl.length() )
+	if (ensureMediaSourceExists())
 	{
-		if (mMediaSource)
-			mMediaSource->navigateTo(mHomePageUrl);
-	};
+		mMediaSource->setSize(mTextureWidth, mTextureHeight);
+		mMediaSource->navigateHome();
+	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -538,6 +551,10 @@ void LLMediaCtrl::navigateHome()
 void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
 {
 	mHomePageUrl = urlIn;
+	if (mMediaSource)
+	{
+		mMediaSource->setHomeURL(mHomePageUrl);
+	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -547,6 +564,21 @@ bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned i
 	//NOOP
 	return false;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setTextureSize(S32 width, S32 height)
+{
+	mTextureWidth = width;
+	mTextureHeight = height;
+	
+	if(mMediaSource)
+	{
+		mMediaSource->setSize(mTextureWidth, mTextureHeight);
+		mForceUpdate = true;
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 std::string LLMediaCtrl::getHomePageUrl()
@@ -554,6 +586,38 @@ std::string LLMediaCtrl::getHomePageUrl()
 	return 	mHomePageUrl;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::ensureMediaSourceExists()
+{	
+	if(mMediaSource.isNull())
+	{
+		// If we don't already have a media source, try to create one.
+		mMediaSource = LLViewerMedia::newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight);
+		if ( mMediaSource )
+		{
+			mMediaSource->setUsedInUI(true);
+			mMediaSource->setHomeURL(mHomePageUrl);
+			mMediaSource->setVisible( getVisible() );
+			mMediaSource->addObserver( this );
+		}
+		else
+		{
+			llwarns << "media source create failed " << llendl;
+			// return;
+		}
+	}
+	
+	return !mMediaSource.isNull();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::unloadMediaSource()
+{
+	mMediaSource = NULL;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
@@ -575,13 +639,17 @@ void LLMediaCtrl::draw()
 	{
 		return;
 	}
+	
+	if(!media_plugin || (!media_plugin->textureValid()))
+	{
+		// Don't try to draw without a valid texture
+		return;
+	}
 
 	LLViewerMediaTexture* media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
 	
 	if (!media_texture )
-	{
 		return;
-	}
 	
 	if ( gRestoreGL == 1 )
 	{
@@ -659,7 +727,7 @@ void LLMediaCtrl::draw()
 			width = llmin(media_plugin->getWidth(), r.getWidth());
 			height = llmin(media_plugin->getHeight(), r.getHeight());
 		}
-
+		
 		x_offset = (r.getWidth() - width) / 2;
 		y_offset = (r.getHeight() - height) / 2;		
 
@@ -775,24 +843,9 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 		case MEDIA_EVENT_CURSOR_CHANGED:
 		{
 			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
-
-			std::string cursor = self->getCursorName();
-			
-			if(cursor == "arrow")
-				mLastSetCursor = UI_CURSOR_ARROW;
-			else if(cursor == "ibeam")
-				mLastSetCursor = UI_CURSOR_IBEAM;
-			else if(cursor == "splith")
-				mLastSetCursor = UI_CURSOR_SIZEWE;
-			else if(cursor == "splitv")
-				mLastSetCursor = UI_CURSOR_SIZENS;
-			else if(cursor == "hand")
-				mLastSetCursor = UI_CURSOR_HAND;
-			else // for anything else, default to the arrow
-				mLastSetCursor = UI_CURSOR_ARROW;
-		};
+		}
 		break;
-		
+			
 		case MEDIA_EVENT_NAVIGATE_BEGIN:
 		{
 			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
@@ -898,15 +951,7 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
 			if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
 				 LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
 			{
-				// If we spawn a new LLFloaterHTML, assume we want it to
-				// follow this LLMediaCtrl's trust for whether or
-				// not to open secondlife:///app/ links. JC.
-//				const bool open_links_externally = false;
-//				LLFloaterHtml::getInstance()->show( 
-//					event_in.mStringPayload, 
-//						"Second Life Browser",
-//							open_links_externally,
-//								mTrusted);
+				llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
 			}
 		}
 	}
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index a19b3ad67bc3cea727f0edc3b7d1a03e322fcc4f..5ea03f1e6c0fabae03edb15552255306e0af2272 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -37,7 +37,6 @@
 
 #include "lluictrl.h"
 #include "llframetimer.h"
-#include "lldynamictexture.h"
 
 class LLViewBorder;
 class LLUICtrlFactory;
@@ -50,7 +49,6 @@ class LLMediaCtrl :
 	public LLViewerMediaEventEmitter
 {
 	LOG_CLASS(LLMediaCtrl);
-
 public:
 	struct Params : public LLInitParam::Block<Params, LLPanel::Params> 
 	{
@@ -58,7 +56,11 @@ class LLMediaCtrl :
 		
 		Optional<bool>			border_visible,
 								ignore_ui_scale,
-								hide_loading;
+								hide_loading,
+								decouple_texture_size;
+								
+		Optional<S32>			texture_width,
+								texture_height;
 		
 		Optional<LLUIColor>		caret_color;
 		
@@ -127,9 +129,17 @@ class LLMediaCtrl :
 		void setForceUpdate(bool force_update) { mForceUpdate = force_update; }
 		bool getForceUpdate() { return mForceUpdate; }
 
+		bool ensureMediaSourceExists();
+		void unloadMediaSource();
+		
 		LLPluginClassMedia* getMediaPlugin();
 
 		bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue );
+		
+		void setDecoupleTextureSize(bool decouple) { mDecoupleTextureSize = decouple; }
+		bool getDecoupleTextureSize() { return mDecoupleTextureSize; }
+
+		void setTextureSize(S32 width, S32 height);
 
 
 		// over-rides
@@ -173,10 +183,12 @@ class LLMediaCtrl :
 		bool mAlwaysRefresh;
 		viewer_media_t mMediaSource;
 		bool mTakeFocusOnClick;
-		ECursorType mLastSetCursor;
 		bool mStretchToFill;
 		bool mMaintainAspectRatio;
 		bool mHideLoading;
+		bool mDecoupleTextureSize;
+		S32 mTextureWidth;
+		S32 mTextureHeight;
 };
 
 #endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index b1db51dd26a58c27fbaa31c780fe42654dfd4134..19fee20740069001b023980de40fc34645880637 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -317,6 +317,7 @@ void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
 void LLNavigationBar::onLocationSelection()
 {
 	std::string typed_location = mCmbLocation->getSimple();
+	LLStringUtil::trim(typed_location);
 
 	// Will not teleport to empty location.
 	if (typed_location.empty())
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b53bb586f39078c8a1538b746d5391f5e01ff8bb..843093793369efed4d57e892ea51bdae4c26fd71 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -65,6 +65,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) :
 	mChatCaptionPanel(NULL),
 	mChatHistoryEditor(NULL)
 {
+	m_isDirty = false;
 }
 
 LLNearbyChat::~LLNearbyChat()
@@ -181,7 +182,7 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
 	return text_color;
 }
 
-void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
 {
 	std::string line = chat.mText;
 
@@ -194,25 +195,28 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
 	bool prepend_newline = true;
 	if (gSavedSettings.getBOOL("ChatShowTimestamps"))
 	{
-		edit->appendTime(prepend_newline);
+		mChatHistoryEditor->appendTime(prepend_newline);
 		prepend_newline = false;
 	}
 
 	// If the msg is from an agent (not yourself though),
 	// extract out the sender name and replace it with the hotlinked name.
+	
+	std::string		str_URL = chat.mURL;
+
 	if (chat.mSourceType == CHAT_SOURCE_AGENT &&
 		chat.mFromID != LLUUID::null)
 	{
-		chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+		str_URL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
 	}
 
 	// If the chat line has an associated url, link it up to the name.
-	if (!chat.mURL.empty()
+	if (!str_URL.empty()
 		&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
 	{
 		std::string start_line = line.substr(0, chat.mFromName.length() + 1);
 		line = line.substr(chat.mFromName.length() + 1);
-		edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
+		mChatHistoryEditor->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,str_URL));
 		prepend_newline = false;
 	}
 
@@ -225,11 +229,9 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
 	else if (2 == font_size)
 		font_name = "sansserifbig";
 
-	edit->appendColoredText(line, false, prepend_newline, color, font_name);
+	mChatHistoryEditor->appendColoredText(line, false, prepend_newline, color, font_name);
 }
 
-
-
 void	LLNearbyChat::addMessage(const LLChat& chat)
 {
 	LLColor4 color = nearbychat_get_text_color(chat);
@@ -254,7 +256,7 @@ void	LLNearbyChat::addMessage(const LLChat& chat)
 	mChatHistoryEditor->setParseHighlights(TRUE);
 	
 	if (!chat.mMuted)
-		nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
+		add_timestamped_line(chat, color);
 }
 
 void LLNearbyChat::onNearbySpeakers()
@@ -482,9 +484,16 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 void	LLNearbyChat::onOpen(const LLSD& key )
 {
-	LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
 	if(chat_channel)
 	{
 		chat_channel->removeToastsFromChannel();
 	}
 }
+
+void	LLNearbyChat::draw		()
+{
+	LLFloater::draw();
+}
+
+
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index efa2e479e66a28536b4ef98c7ee3b71c0a0e9f84..599e6b6859ad132ed228472d229be4b99ee9d94e 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -76,7 +76,10 @@ class LLNearbyChat: public LLFloater
 
 	virtual void	onOpen		(const LLSD& key);
 
+	virtual void	draw		();
+
 private:
+	void	add_timestamped_line(const LLChat& chat, const LLColor4& color);
 	
 	void	pinn_panel();
 	void	float_panel();
@@ -86,10 +89,11 @@ class LLNearbyChat: public LLFloater
 	S32		mStart_X;
 	S32		mStart_Y;
 
-	//LLResizeBar*		mResizeBar[RESIZE_BAR_COUNT];
 	LLHandle<LLView>	mPopupMenuHandle;
 	LLPanel*			mChatCaptionPanel;
 	LLViewerTextEditor*	mChatHistoryEditor;
+
+	bool				m_isDirty;
 };
 
 #endif
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index cec4b9f7c7493fa6499cd7463977805e2eca0dee..1d8789fde0afc366743b485c847ff6d856690b6e 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -190,7 +190,7 @@ BOOL LLNearbyChatBar::postBuild()
 
 	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
 	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
-	mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this);
+	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
 
 	mChatBox->setIgnoreArrowKeys(TRUE);
 	mChatBox->setCommitOnFocusLost( FALSE );
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 7eb5d91e539a3d3127550474edfdce3ce4def809..eb42e83994f3a147720e42539a49f8e6baa71f76 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -41,30 +41,227 @@
 #include "llviewercontrol.h"
 
 #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
 
 //add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
+using namespace LLNotificationsUI;
 
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------	
+LLToastPanelBase* createToastPanel()
+{
+	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
+	static S32 chat_item_width = 304;
+	item->setWidth(chat_item_width);
+	return item;
+}
+
+
+class LLNearbyChatScreenChannel: public LLScreenChannelBase
+{
+public:
+	LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;};
 
+	void init				(S32 channel_left, S32 channel_right);
+
+	void addNotification	(LLSD& notification);
+	void arrangeToasts		();
+	void showToastsBottom	();
+	
+	typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+	void onToastDestroyed	(LLToast* toast);
+	void onToastFade		(LLToast* toast);
+
+	// hide all toasts from screen, but not remove them from a channel
+	virtual void		hideToastsFromScreen() 
+	{
+	};
+	// removes all toasts from a channel
+	virtual void		removeToastsFromChannel() 
+	{
+		for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+		{
+			LLToast* toast = (*it);
+			toast->setVisible(FALSE);
+			toast->stopTimer();
+			m_toast_pool.push_back(toast);
+
+		}
+		m_active_toasts.clear();
+	};
+
+protected:
+	void	createOverflowToast(S32 bottom, F32 timer);
+
+	create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+	bool	createPoolToast();
+	
+	std::vector<LLToast*> m_active_toasts;
+	std::list<LLToast*> m_toast_pool;
+
+	S32 mActiveMessages;
+};
+
+void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom;
+	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+	setVisible(TRUE);
+}
+
+
+void	LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+	//we don't need overflow toast in nearby chat
+}
+
+void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast)
+{	
+}
+
+void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{	
+	//fade mean we put toast to toast pool
+	if(!toast)
+		return;
+	m_toast_pool.push_back(toast);
+
+	std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);
+	if(pos!=m_active_toasts.end())
+		m_active_toasts.erase(pos);
+	
+	arrangeToasts();
+}
+
+
+bool	LLNearbyChatScreenChannel::createPoolToast()
+{
+	LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+	if(!panel)
+		return false;
+	
+	LLToast::Params p;
+	p.panel = panel;
+
+	LLToast* toast = new LLToast(p); 
+	
+	
+	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
+	toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
+	
+	m_toast_pool.push_back(toast);
+	return true;
+}
+
+void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+{
+	//look in pool. if there is any message
+
+	
+	if(m_toast_pool.empty())
+	{
+		//"pool" is empty - create one more panel
+		if(!createPoolToast())//created toast will go to pool. so next call will find it
+			return;
+		addNotification(notification);
+		return;
+	}
+
+	//take 1st element from pool, (re)initialize it, put it in active toasts
+
+	LLToast* toast = m_toast_pool.back();
+
+	m_toast_pool.pop_back();
+
+
+	LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+	if(!panel)
+		return;
+	panel->init(notification);
+
+	toast->reshapeToPanel();
+	toast->resetTimer();
+	
+	m_active_toasts.insert(m_active_toasts.begin(),toast);
+
+	arrangeToasts();
+}
+
+void LLNearbyChatScreenChannel::arrangeToasts()
+{
+	if(m_active_toasts.size() == 0 || mIsHovering)
+		return;
+
+	hideToastsFromScreen();
+
+	showToastsBottom();					
+}
+
+void LLNearbyChatScreenChannel::showToastsBottom()
+{
+	LLRect rect = getRect();
+
+	LLRect	toast_rect;	
+	S32		bottom = getRect().mBottom;
+
+	for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+	{
+		LLToast* toast = (*it);
+		toast_rect = toast->getRect();
+		toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+		
+		toast->setRect(toast_rect);
+
+		if(toast->getRect().mTop > getRect().getHeight())
+		{
+			while(it!=m_active_toasts.end())
+			{
+				(*it)->setVisible(FALSE);
+				(*it)->stopTimer();
+				m_toast_pool.push_back(*it);
+				it=m_active_toasts.erase(it);
+			}
+			break;
+		}
+		toast->setVisible(TRUE);
+		bottom = toast->getRect().mTop;
+	}
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
 LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
 {
 	mType = type;
-	LLChannelManager::Params p;
-	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
 
 	// Getting a Channel for our notifications
-	mChannel = LLChannelManager::getInstance()->getChannel(p);
+	LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	
+	LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+	channel->setCreatePanelCallback(callback);
+
+	mChannel = LLChannelManager::getInstance()->addChannel(channel);
 	mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
 }
+
 LLNearbyChatHandler::~LLNearbyChatHandler()
 {
 }
 
+
 void LLNearbyChatHandler::initChannel()
 {
 	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
 	S32 channel_right_bound = nearby_chat->getRect().mRight;
-	S32 channel_width = nearby_chat->getRect().mRight - 16;   //HACK: 16 - ?
+	S32 channel_width = nearby_chat->getRect().mRight; 
 	mChannel->init(channel_right_bound - channel_width, channel_right_bound);
 }
 
@@ -77,41 +274,42 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
 
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
-
+	
 	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
 	nearby_chat->addMessage(chat_msg);
 	if(nearby_chat->getVisible())
 		return;//no need in toast if chat is visible
-
+	
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
-	
+
 	LLUUID id;
 	id.generate();
 
-	LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-	
-	item->setMessage(chat_msg);
-	//static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
-	static S32 chat_item_width = 304;
-	item->setWidth(chat_item_width);
-	item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+	LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel);
 	
-	item->setVisible(true);
 
-	LLToast::Params p;
-	p.notif_id = id;
-	p.panel = item;
-	p.on_delete_toast = boost::bind(&LLNearbyChatHandler::onDeleteToast, this, _1);
-	mChannel->addToast(p);	
+	if(channel)
+	{
+		LLSD notification;
+		notification["id"] = id;
+		notification["message"] = chat_msg.mText;
+		notification["from"] = chat_msg.mFromName;
+		notification["from_id"] = chat_msg.mFromID;
+		notification["time"] = chat_msg.mTime;
+		notification["source"] = (S32)chat_msg.mSourceType;
+
+		channel->addNotification(notification);	
+	}
+	
 }
 
 void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
 {
 }
 
-}
+
 
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 3893eaa0d4e1c0d9a2b8a343f71c2b89bf7328d1..1be03cef0b57be4e2f05e28ad5e1954761eaea06 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -55,7 +55,7 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo
 
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->getChannel(p);
-	mChannel->setShowToasts(true);
+	mChannel->setCanStoreToasts(false);
 }
 
 //--------------------------------------------------------------------------
@@ -100,16 +100,23 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
 		p.can_fade = false;
 		p.is_modal = mIsModal;
 		p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 	}
 	else if (notify["sigtype"].asString() == "change")
 	{
 		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
 	}
 	else
 	{
-		mChannel->killToastByNotificationID(notification->getID());
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->killToastByNotificationID(notification->getID());
 	}
 	return true;
 }
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index c488d37ea5a67763a71534183701a2b91037aef6..ffa92b543cc459344760b7ce7b24effd47fae34d 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -89,7 +89,10 @@ bool LLGroupHandler::processNotification(const LLSD& notify)
 		p.notification = notification;
 		p.panel = notify_box;
 		p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager
 		mNewNotificationSignal();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 90ff5fbaaca212ea1abb84b1069c470bd29b3bdc..cd4e640ec4896b060430b9e348d52a2378ca03a4 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -104,8 +104,8 @@ class LLEventHandler
 	// at the moment, when a handlers creates a channel.
 	virtual void initChannel()=0;
 
-	LLScreenChannel*	mChannel;
-	e_notification_type	mType;
+	LLScreenChannelBase*	mChannel;
+	e_notification_type		mType;
 
 };
 
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 72855ac0fda7aff8a77d76b0c7539a8ed902b5e5..070af432d6cd48c781cb341689acf6649fe41348 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -48,7 +48,11 @@ LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 	mChannel->setControlHovering(true);
-	mChannel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+	
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
 }
 
 //--------------------------------------------------------------------------
@@ -92,7 +96,10 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
 		p.notification = notification;
 		p.panel = notify_box;	
 		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager
 		mNewNotificationSignal();
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 740acb63659fbe774ac229fcbe4de7ee15f02189..5186a9356947fd1357a743c6dde530bd1fcd2a1f 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -93,8 +93,9 @@ bool LLTipHandler::processNotification(const LLSD& notify)
 		p.is_tip = true;
 		p.can_be_stored = false;
 		
-		mChannel->addToast(p);
-
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 	}
 	else if (notify["sigtype"].asString() == "delete")
 	{
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 6e1dc6940ea047da963f6bc932379aef5de71e3e..d9cdf2e04fccd40f57b616d07128ef5abe137919 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -129,7 +129,7 @@ void LLOutputMonitorCtrl::draw()
 	const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
 	const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
 
-	if (mIsParentVisible && getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
+	if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
 	{
 		setPower(gVoiceClient->getCurrentPower(mSpeakerId));
 		setIsTalking(gVoiceClient->getIsSpeaking(mSpeakerId));
@@ -220,12 +220,6 @@ void LLOutputMonitorCtrl::draw()
 		gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
 }
 
-void LLOutputMonitorCtrl::handleVisibilityChange(BOOL new_visibility)
-{
-	mIsParentVisible = new_visibility;
-	LLView::handleVisibilityChange(new_visibility);
-}
-
 void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id)
 {
 	if (speaker_id.isNull()) return;
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 0e213c4326fc8b8254bc62d3adc1b348e61572dd..7a7b8bc3a18e5fcdf799fd67cb8c3b769334b676 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -72,8 +72,6 @@ class LLOutputMonitorCtrl
 
 	// llview overrides
 	virtual void	draw();
-	void handleVisibilityChange(BOOL new_visibility);
-
 
 	void			setPower(F32 val);
 	F32				getPower(F32 val) const { return mPower; }
@@ -104,8 +102,6 @@ class LLOutputMonitorCtrl
 	F32				mPower;
 	bool			mIsMuted;
 	bool			mIsTalking;
-	/** Stores flag whether parent is visible. If not it will not update indicator*/
-	bool			mIsParentVisible;
 	LLPointer<LLUIImage> mImageMute;
 	LLPointer<LLUIImage> mImageOff;
 	LLPointer<LLUIImage> mImageOn;
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 649697e0912489fee46bd5cb0f24198cb28535b2..7ccff730804c84e1ae3cef9607d33edd142e0042 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -313,7 +313,7 @@ void LLPanelProfileTab::scrollToTop()
 {
 	LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
 	if (scrollContainer)
-	scrollContainer->goToTop();
+		scrollContainer->goToTop();
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index ee5d2652203712d7e9a0e253b956a77d68bce9a2..7eaee92778e003ccfec0b734066cf8b52b6a7e73 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -238,13 +238,13 @@ BOOL LLPanelClassified::postBuild()
     mNameEditor = getChild<LLLineEditor>("given_name_editor");
 	mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN);
 	mNameEditor->setCommitOnFocusLost(TRUE);
-	mNameEditor->setFocusReceivedCallback(focusReceived, this);
+	mNameEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
 	mNameEditor->setCommitCallback(onCommitAny, this);
 	mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
 
     mDescEditor = getChild<LLTextEditor>("desc_editor");
 	mDescEditor->setCommitOnFocusLost(TRUE);
-	mDescEditor->setFocusReceivedCallback(focusReceived, this);
+	mDescEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
 	mDescEditor->setCommitCallback(onCommitAny, this);
 	
     mLocationEditor = getChild<LLLineEditor>("location_editor");
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 5da646497b3cc5835b87b50bf0a595ea6618f403..ea528a1df89e38e8db18e233df02827a5ad9dcdd 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -72,6 +72,13 @@
 //
 // Globals
 //
+const char* LLPanelContents::TENTATIVE_SUFFIX = "_tentative";
+const char* LLPanelContents::PERMS_OWNER_INTERACT_KEY = "perms_owner_interact";
+const char* LLPanelContents::PERMS_OWNER_CONTROL_KEY = "perms_owner_control";
+const char* LLPanelContents::PERMS_GROUP_INTERACT_KEY = "perms_group_interact";
+const char* LLPanelContents::PERMS_GROUP_CONTROL_KEY = "perms_group_control";
+const char* LLPanelContents::PERMS_ANYONE_INTERACT_KEY = "perms_anyone_interact";
+const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
 
 BOOL LLPanelContents::postBuild()
 {
@@ -83,7 +90,7 @@ BOOL LLPanelContents::postBuild()
 	childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
 
 	mPanelInventory = getChild<LLPanelInventory>("contents_inventory");
-	
+
 	return TRUE;
 }
 
@@ -112,7 +119,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
 	LLSelectMgr::getInstance()->selectGetGroup(group_id);  // sets group_id as a side effect SL-23488
 
 	// BUG? Check for all objects being editable?
-	BOOL editable = gAgent.isGodlike()
+	bool editable = gAgent.isGodlike()
 					|| (objectp->permModify()
 					       && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) )));  // solves SL-23488
 	BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
@@ -123,8 +130,8 @@ void LLPanelContents::getState(LLViewerObject *objectp )
 		all_volume &&
 		((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
 			|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
-}
 
+}
 
 void LLPanelContents::refresh()
 {
@@ -135,7 +142,7 @@ void LLPanelContents::refresh()
 	if (mPanelInventory)
 	{
 		mPanelInventory->refresh();
-	}
+	}	
 }
 
 
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index de1914bff9c879f834e46ea3d4917ffe5f322e21..bab980b52461d0c0cb7b0d736ed3164d31ba13ea 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -51,11 +51,23 @@ class LLPanelContents : public LLPanel
 
 	void			refresh();
 
-	static void		onClickNewScript(		void* userdata);
-	static void		onClickPermissions(		void* userdata);
+
+	static void		onClickNewScript(void*);
+	static void		onClickPermissions(void*);
+	
+    // Key suffix for "tentative" fields
+    static const char* TENTATIVE_SUFFIX;
+
+    // These aren't fields in LLMediaEntry, so we have to define them ourselves for checkbox control
+    static const char* PERMS_OWNER_INTERACT_KEY;
+    static const char* PERMS_OWNER_CONTROL_KEY;
+    static const char* PERMS_GROUP_INTERACT_KEY;
+    static const char* PERMS_GROUP_CONTROL_KEY;
+    static const char* PERMS_ANYONE_INTERACT_KEY;
+    static const char* PERMS_ANYONE_CONTROL_KEY;
 
 protected:
-	void			getState(LLViewerObject *object);
+	void				getState(LLViewerObject *object);
 
 public:
 	LLPanelInventory* mPanelInventory;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 08a50d4b6ea39e96aceb4279c8e1c427e4920be7..c61b987b1cea53702d561c54221444ce6a4cf721 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -49,6 +49,7 @@
 #include "llcombobox.h"
 #include "lldrawpoolbump.h"
 #include "lllineeditor.h"
+#include "llmediaentry.h"
 #include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llspinctrl.h"
@@ -61,6 +62,7 @@
 #include "llviewermedia.h"
 #include "llviewerobject.h"
 #include "llviewerstats.h"
+#include "llvovolume.h"
 #include "lluictrlfactory.h"
 #include "llpluginclassmedia.h"
 
@@ -70,6 +72,18 @@
 
 BOOL	LLPanelFace::postBuild()
 {
+	childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
+	childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+	childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
+	childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
+	childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
+	childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
+	childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
+	childSetAction("button apply",&LLPanelFace::onClickApply,this);
+	childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
+	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
+	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
+
 	LLRect	rect = this->getRect();
 	LLTextureCtrl*	mTextureCtrl;
 	LLColorSwatchCtrl*	mColorSwatch;
@@ -91,7 +105,7 @@ BOOL	LLPanelFace::postBuild()
 		mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
 		mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
 		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
-		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, _2));
+		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
 		mTextureCtrl->setFollowsTop();
 		mTextureCtrl->setFollowsLeft();
 		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
@@ -161,17 +175,6 @@ BOOL	LLPanelFace::postBuild()
 		mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
 	}
 	
-	childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
-	childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
-	childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
-	childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
-	childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
-	childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
-	childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
-	childSetAction("button apply",&onClickApply,this);
-	childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
-	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
-	childSetAction("button align",onClickAutoFix,this);
 
 	clearCtrls();
 
@@ -382,10 +385,8 @@ void LLPanelFace::getState()
 		BOOL editable = objectp->permModify();
 
 		// only turn on auto-adjust button if there is a media renderer and the media is loaded
-		childSetEnabled("textbox autofix",FALSE);
-		//mLabelTexAutoFix->setEnabled ( FALSE );
-		childSetEnabled("button align",FALSE);
-		//mBtnAutoFix->setEnabled ( FALSE );
+		childSetEnabled("textbox autofix", editable);
+		childSetEnabled("button align", editable);
 		
 		//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
 		//	if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
@@ -785,6 +786,9 @@ void LLPanelFace::getState()
 
 		childSetEnabled("button align",FALSE);
 		childSetEnabled("button apply",FALSE);
+		childSetEnabled("has media", FALSE);
+		childSetEnabled("media info set", FALSE);
+		
 	}
 }
 
@@ -862,7 +866,7 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
 }
 
 // static
-BOOL LLPanelFace::onDragTexture(LLInventoryItem* item)
+BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
 {
 	BOOL accept = TRUE;
 	for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
@@ -917,15 +921,25 @@ void LLPanelFace::onClickApply(void* userdata)
 	LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
 }
 
-// commit the fit media texture to prim button
-
 struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
 {
 	virtual bool apply(LLViewerObject* object, S32 te)
 	{
-		// TODO: the media impl pointer should actually be stored by the texture
-		viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID());
-		// only do this if it's a media texture
+		viewer_media_t pMediaImpl;
+				
+		const LLTextureEntry* tep = object->getTE(te);
+		const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+		if ( mep )
+		{
+			pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+		}
+		
+		if ( pMediaImpl.isNull())
+		{
+			// If we didn't find face media for this face, check whether this face is showing parcel media.
+			pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
+		}
+		
 		if ( pMediaImpl.notNull())
 		{
 			LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
@@ -957,3 +971,14 @@ void LLPanelFace::onClickAutoFix(void* userdata)
 	LLPanelFaceSendFunctor sendfunc;
 	LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
 }
+
+
+
+// TODO: I don't know who put these in or what these are for???
+void LLPanelFace::setMediaURL(const std::string& url)
+{
+}
+void LLPanelFace::setMediaType(const std::string& mime_type)
+{
+}
+
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 96001296963ad781eafbefff4ba42c77b666518a..6a8704ce1450ebd5a0ff6af1bb3f4b0976cd716d 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,7 @@ class LLTextBox;
 class LLTextureCtrl;
 class LLUICtrl;
 class LLViewerObject;
+class LLFloater;
 
 class LLPanelFace : public LLPanel
 {
@@ -56,6 +57,8 @@ class LLPanelFace : public LLPanel
 	virtual ~LLPanelFace();
 
 	void			refresh();
+	void			setMediaURL(const std::string& url);
+	void			setMediaType(const std::string& mime_type);
 
 protected:
 	void			getState();
@@ -69,9 +72,10 @@ class LLPanelFace : public LLPanel
 	void			sendShiny();			// applies and sends shininess
 	void			sendFullbright();		// applies and sends full bright
 	void            sendGlow();
+	void			sendMedia();
 
 	// this function is to return TRUE if the drag should succeed.
-	static BOOL onDragTexture(LLInventoryItem* item);
+	static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
 
 	void 	onCommitTexture(const LLSD& data);
 	void 	onCancelTexture(const LLSD& data);
@@ -87,10 +91,11 @@ class LLPanelFace : public LLPanel
 	static void		onCommitShiny(			LLUICtrl* ctrl, void* userdata);
 	static void		onCommitFullbright(		LLUICtrl* ctrl, void* userdata);
 	static void     onCommitGlow(           LLUICtrl* ctrl, void *userdata);
-
+	
 	static void		onClickApply(void*);
 	static void		onClickAutoFix(void*);
 	static F32      valueGlow(LLViewerObject* object, S32 face);
+
 };
 
 #endif
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 490c845c949ec7499ad82d29b246673e388d0ab7..2b584910a35329d778cbe4a6129d5f420968a0f0 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -195,7 +195,7 @@ BOOL LLPanelGroup::postBuild()
 	if(panel_land)		mTabs.push_back(panel_land);
 
 	if(panel_general)
-	panel_general->setupCtrls(this);
+		panel_general->setupCtrls(this);
 	
 	return TRUE;
 }
@@ -206,8 +206,8 @@ void LLPanelGroup::reposButton(const std::string& name)
 	if(!button)
 		return;
 	LLRect btn_rect = button->getRect();
-		btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
-		button->setRect(btn_rect);
+	btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+	button->setRect(btn_rect);
 }
 
 void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
@@ -235,7 +235,14 @@ void LLPanelGroup::onBtnCreate()
 	if(!panel_general)
 		return;
 	std::string apply_mesg;
-	panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
+	if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
+		return;
+	if ( !apply_mesg.empty() )
+	{
+		LLSD args;
+		args["MESSAGE"] = apply_mesg;
+		LLNotifications::instance().add("GenericAlert", args);
+	}
 }
 
 void LLPanelGroup::onBtnRefresh(void* user_data)
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index d63fd141b0bc7d81cabb49a2121510c529c59c81..2e1d971995339b1ccf8e1000046bf74753876dc3 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -99,8 +99,8 @@ BOOL LLPanelGroupGeneral::postBuild()
 	if(mEditCharter)
 	{
 		mEditCharter->setCommitCallback(onCommitAny, this);
-		mEditCharter->setFocusReceivedCallback(onFocusEdit, this);
-		mEditCharter->setFocusChangedCallback(onFocusEdit, this);
+		mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
+		mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
 	}
 
 
@@ -835,6 +835,7 @@ void LLPanelGroupGeneral::reset()
 	{
 		std::string empty_str = "";
 		mEditCharter->setText(empty_str);
+		mGroupNameEditor->setText(empty_str);
 	}
 	
 	{
@@ -850,6 +851,7 @@ void LLPanelGroupGeneral::reset()
 	{
 		mComboMature->setEnabled(true);
 		mComboMature->setVisible( !gAgent.isTeen() );
+		mComboMature->selectFirstItem();
 	}
 
 
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 378a09e31544c95af6c401cdd3c7e42350fcefec..99bb760b619003feec60a699e8b31ff68103b4c0 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1730,7 +1730,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
 
 	mRoleDescription->setCommitOnFocusLost(TRUE);
 	mRoleDescription->setCommitCallback(onDescriptionCommit, this);
-	mRoleDescription->setFocusReceivedCallback(onDescriptionFocus, this);
+	mRoleDescription->setFocusReceivedCallback(boost::bind(onDescriptionFocus, _1, this));
 
 	setFooterEnabled(FALSE);
 
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index 994bf7e3f9c7dba86fc611ce2a6e2fe85739a644..42ad9820a818848a8ef8bac1b8f794e0e7ce5a89 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -122,9 +122,6 @@ BOOL LLPanelLandMedia::postBuild()
 	mSetURLButton = getChild<LLButton>("set_media_url");
 	childSetAction("set_media_url", onSetBtn, this);
 
-	mResetURLButton = getChild<LLButton>("reset_media_url");
-	childSetAction("reset_media_url", onResetBtn, this);
-
 	return TRUE;
 }
 
@@ -215,13 +212,7 @@ void LLPanelLandMedia::refresh()
 		mMediaTextureCtrl->setEnabled( can_change_media );
 
 		mSetURLButton->setEnabled( can_change_media );
-		mResetURLButton->setEnabled( can_change_media );
 
-		LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
-		if (floater_url_entry)
-		{
-			floater_url_entry->updateFromLandMediaPanel();
-		}
 	}
 }
 
@@ -341,7 +332,7 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
 void LLPanelLandMedia::onSetBtn(void *userdata)
 {
 	LLPanelLandMedia *self = (LLPanelLandMedia *)userdata;
-	self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() );
+	self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle(), self->getMediaURL() );
 	LLFloater* parent_floater = gFloaterView->getParentFloater(self);
 	if (parent_floater)
 	{
diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h
index 5ad1f9758d7a27adf5ee5edca862f65d5573459f..3deea29d17f42de423ca04bf2d6c55990ebfdcb4 100644
--- a/indra/newview/llpanellandmedia.h
+++ b/indra/newview/llpanellandmedia.h
@@ -63,8 +63,6 @@ class LLPanelLandMedia
 	LLLineEditor*	mMediaDescEdit;
 	LLComboBox*		mMediaTypeCombo;
 	LLButton*		mSetURLButton;
-	LLButton*		mResetURLButton;
-	LLSpinCtrl*		mMediaResetCtrl;
 	LLSpinCtrl*		mMediaHeightCtrl;
 	LLSpinCtrl*		mMediaWidthCtrl;
 	LLTextBox*		mMediaResetCtrlLabel;
@@ -74,13 +72,6 @@ class LLPanelLandMedia
 	LLCheckBoxCtrl*	mMediaLoopCheck;
 	LLCheckBoxCtrl* mMediaUrlCheck;
 	LLHandle<LLFloater>	mURLEntryFloater;
-	LLCheckBoxCtrl* mMediaNavigateAllowCheck;
-	LLCheckBoxCtrl* mMediaURLFilterCheck;
-	LLLineEditor*	mMediaURLFilterDomainEdit;
-	LLButton*		mMediaURLFilterAddButton;
-	LLButton*		mMediaURLFilterRemoveButton;
-	LLScrollListCtrl*   mURLFilterList;
-	LLRadioGroup*	mRadioNavigateControl;
 
 
 	
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 150fd399c638890d4bfff1ed05d0863e1597497f..a7f66f32938ab849e320255ca3ab277c98e24308 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -57,6 +57,7 @@
 #include "lluiconstants.h"
 #include "llurlsimstring.h"
 #include "llviewerbuild.h"
+#include "llviewerhelp.h"
 #include "llviewertexturelist.h"
 #include "llviewermenu.h"			// for handle_preferences()
 #include "llviewernetwork.h"
@@ -69,7 +70,7 @@
 #include "llmediactrl.h"
 #include "llrootview.h"
 
-#include "llfloatermediabrowser.h"
+
 #include "llfloatertos.h"
 #include "lltrans.h"
 #include "llglheaders.h"
@@ -229,7 +230,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
 	server_choice_combo->setCommitCallback(onSelectServer, NULL);
-	server_choice_combo->setFocusLostCallback(onServerComboLostFocus);
+	server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
 
 	childSetAction("connect_btn", onClickConnect, this);
 
@@ -412,8 +413,8 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
 
 	if ( KEY_F1 == key )
 	{
-		llinfos << "Spawning HTML help window" << llendl;
-		gViewerHtmlHelp.show();
+		LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+		vhelp->showTopic(vhelp->getTopicFromFocus());
 		return TRUE;
 	}
 
@@ -973,7 +974,7 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
 	loadLoginPage();
 }
 
-void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
+void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
 {
 	if (!sInstance) return;
 
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index ffcf6a9b70c390c17f70ed27fee934c4d6f26c45..5692b8d345a392365c75deea1dc1e3364799c4a2 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -94,7 +94,7 @@ class LLPanelLogin:
 	static void onClickForgotPassword(void*);
 	static void onPassKey(LLLineEditor* caller, void* user_data);
 	static void onSelectServer(LLUICtrl*, void*);
-	static void onServerComboLostFocus(LLFocusableElement*, void*);
+	static void onServerComboLostFocus(LLFocusableElement*);
 	
 private:
 	LLPointer<LLUIImage> mLogoImage;
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..be40d6fb5f3689f9653db33a5693c130a97ab285
--- /dev/null
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -0,0 +1,409 @@
+/**
+ * @file llpanelmediasettingsgeneral.cpp
+ * @brief LLPanelMediaSettingsGeneral class implementation
+ *
+ * $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 "llviewerprecompiledheaders.h"
+
+#include "llpanelmediasettingsgeneral.h"
+#include "llcombobox.h"
+#include "llcheckboxctrl.h"
+#include "llspinctrl.h"
+#include "lluictrlfactory.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llbutton.h"
+#include "lltexturectrl.h"
+#include "llurl.h"
+#include "llwindow.h"
+#include "llmediaentry.h"
+#include "llmediactrl.h"
+#include "llpanelcontents.h"
+#include "llpluginclassmedia.h"
+#include "llfloatermediasettings.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() :
+	mControls( NULL ),
+	mAutoLoop( NULL ),
+	mFirstClick( NULL ),
+	mAutoZoom( NULL ),
+	mAutoPlay( NULL ),
+	mAutoScale( NULL ),
+	mWidthPixels( NULL ),
+	mHeightPixels( NULL ),
+	mHomeURL( NULL ),
+	mCurrentURL( NULL ),
+	mAltImageEnable( NULL ),
+	mParent( NULL )
+{
+	// build dialog from XML
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml");
+	mCommitCallbackRegistrar.add("Media.ResetCurrentUrl",		boost::bind(&LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl, this));
+//	mCommitCallbackRegistrar.add("Media.CommitHomeURL",			boost::bind(&LLPanelMediaSettingsGeneral::onCommitHomeURL, this));	
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsGeneral::postBuild()
+{
+	// connect member vars with UI widgets
+    mAltImageEnable = getChild< LLCheckBoxCtrl >( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
+	mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY );
+	mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY );
+	mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
+	mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
+	mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY );
+	mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY );
+	mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
+	mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
+	mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
+	mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY );
+	mPreviewMedia = getChild<LLMediaCtrl>("preview_media");
+
+	// watch commit action for HOME URL
+	childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
+
+	// interrogates controls and updates widgets as required
+	updateMediaPreview();
+	updateCurrentURL();
+
+	return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::draw()
+{
+	// housekeeping
+	LLPanel::draw();
+
+	// enable/disable pixel values image entry based on auto scale checkbox 
+	if ( mAutoScale->getValue().asBoolean() == false )
+	{
+		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, true );
+		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, true );
+	}
+	else
+	{
+		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, false );
+		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, false );
+	};
+
+	// enable/disable UI based on type of media
+	bool reset_button_is_active = true;
+	if( mPreviewMedia )
+	{
+		LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
+		if( media_plugin )
+		{
+			// some controls are only appropriate for time or browser type plugins
+			// so we selectively enable/disable them - need to do it in draw
+			// because the information from plugins arrives assynchronously
+			bool show_time_controls = media_plugin->pluginSupportsMediaTime();
+			if ( show_time_controls )
+			{
+				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, false );
+				reset_button_is_active = false;
+				childSetEnabled( "current_url_label", false );
+				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, true );
+			}
+			else
+			{
+				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, true );
+				reset_button_is_active = true;
+				childSetEnabled( "current_url_label", true );
+				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, false );
+			};
+		};
+	};
+
+	// current URL can change over time.
+	updateCurrentURL();
+
+	// enable/disable RESRET button depending on permissions
+	// since this is the same as a navigate action
+	U32 owner_mask_on;
+	U32 owner_mask_off;
+	U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER, 
+												&owner_mask_on, &owner_mask_off );
+	U32 group_mask_on;
+	U32 group_mask_off;
+	U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP, 
+												&group_mask_on, &group_mask_off );
+	U32 everyone_mask_on;
+	U32 everyone_mask_off;
+	S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE, 
+												&everyone_mask_on, &everyone_mask_off );
+	
+	bool user_can_press_reset = false;
+
+	// if perms we got back are valid
+	if ( valid_owner_perms &&
+		 valid_group_perms && 
+		 valid_everyone_perms )
+	{
+		// if user is allowed to press the RESET button
+		if ( ( owner_mask_on & PERM_MODIFY ) ||
+			 ( group_mask_on & PERM_MODIFY ) || 
+			 ( group_mask_on & PERM_MODIFY ) )
+		{
+			user_can_press_reset = true;
+		}
+		else
+		// user is NOT allowed to press the RESET button
+		{
+			user_can_press_reset = false;
+		};
+	};
+
+	// several places modify this widget so we must collect states in one place
+	if ( reset_button_is_active )
+	{
+		// user has perms to press reset button and it is active
+		if ( user_can_press_reset )
+		{
+			childSetEnabled( "current_url_reset_btn", true );
+		}
+		// user does not has perms to press reset button and it is active
+		else
+		{
+			childSetEnabled( "current_url_reset_btn", false );
+		};
+	}
+	else
+	// reset button is inactive so we just slam it to off - other states don't matter
+	{
+		childSetEnabled( "current_url_reset_btn", false );
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsGeneral::clearValues( void* userdata )
+{	
+	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+	self->mAltImageEnable ->clear();
+	self->mAutoLoop->clear();
+	self->mAutoPlay->clear();
+	self->mAutoScale->clear();
+	self->mAutoZoom ->clear();
+	self->mControls->clear();
+	self->mCurrentURL->clear();
+	self->mFirstClick->clear();
+	self->mHeightPixels->clear();
+	self->mHomeURL->clear();
+	self->mWidthPixels->clear();
+	self->mPreviewMedia->unloadMediaSource(); 
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings )
+{
+	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+
+	//llinfos << "---------------" << llendl;
+	//llinfos << ll_pretty_print_sd(media_settings) << llendl;
+	//llinfos << "---------------" << llendl;
+
+	std::string base_key( "" );
+	std::string tentative_key( "" );
+
+	struct 
+	{
+		std::string key_name;
+		LLUICtrl* ctrl_ptr;
+		std::string ctrl_type;
+
+	} data_set [] = 
+	{ 
+        { LLMediaEntry::AUTO_LOOP_KEY,				self->mAutoLoop,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::AUTO_PLAY_KEY,				self->mAutoPlay,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::AUTO_SCALE_KEY,				self->mAutoScale,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::AUTO_ZOOM_KEY,				self->mAutoZoom,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::CONTROLS_KEY,				self->mControls,		"LLComboBox" },
+		{ LLMediaEntry::CURRENT_URL_KEY,			self->mCurrentURL,		"LLLineEditor" },
+		{ LLMediaEntry::HEIGHT_PIXELS_KEY,			self->mHeightPixels,	"LLSpinCtrl" },
+		{ LLMediaEntry::HOME_URL_KEY,				self->mHomeURL,			"LLLineEditor" },
+		{ LLMediaEntry::FIRST_CLICK_INTERACT_KEY,	self->mFirstClick,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::WIDTH_PIXELS_KEY,			self->mWidthPixels,		"LLSpinCtrl" },
+		{ LLMediaEntry::ALT_IMAGE_ENABLE_KEY,		self->mAltImageEnable,	"LLCheckBoxCtrl" },
+		{ "", NULL , "" }
+	};
+
+	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+	{
+		base_key = std::string( data_set[ i ].key_name );
+		tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+		// TODO: CP - I bet there is a better way to do this using Boost
+		if ( media_settings[ base_key ].isDefined() )
+		{
+			if ( data_set[ i ].ctrl_type == "LLLineEditor" )
+			{
+				static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )->
+					setText( media_settings[ base_key ].asString() );
+			}
+			else
+			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+					setValue( media_settings[ base_key ].asBoolean() );
+			else
+			if ( data_set[ i ].ctrl_type == "LLComboBox" )
+				static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
+					setCurrentByIndex( media_settings[ base_key ].asInteger() );
+			else
+			if ( data_set[ i ].ctrl_type == "LLSpinCtrl" )
+				static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->
+					setValue( media_settings[ base_key ].asInteger() );
+
+			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+		};
+	};
+
+	// interrogates controls and updates widgets as required
+	self->updateMediaPreview();
+	self->updateCurrentURL();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper to set media control to media URL as required
+void LLPanelMediaSettingsGeneral::updateMediaPreview()
+{
+	if ( mHomeURL->getValue().asString().length() > 0 )
+	{
+		mPreviewMedia->navigateTo( mHomeURL->getValue().asString() );
+	}
+	else
+	// new home URL will be empty if media is deleted but
+	// we still need to clean out the preview.
+	{
+		mPreviewMedia->unloadMediaSource();
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper to set current URL
+void LLPanelMediaSettingsGeneral::updateCurrentURL()
+{
+	if( mPreviewMedia )
+	{
+		LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
+		if( media_plugin )
+		{
+			// get current URL from plugin and display
+			std::string current_location = media_plugin->getLocation();
+			if ( current_location.length() )
+			{
+				childSetText( "current_url", current_location );
+			}
+			else
+			// current location may be empty so we need to clear it
+			{
+				const std::string empty_string( "" );
+				childSetText( "current_url", empty_string );
+			};
+		};
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void LLPanelMediaSettingsGeneral::onClose()
+{
+	if(mPreviewMedia)
+	{
+		mPreviewMedia->unloadMediaSource();
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata )
+{
+	LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
+	self->updateMediaPreview();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl()
+{
+	// TODO: reset home URL but need to consider permissions too
+	//LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsGeneral::apply( void* userdata )
+{
+	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
+
+	// build LLSD Fragment
+	LLSD media_data_general;
+	self->getValues(media_data_general);
+
+	// this merges contents of LLSD passed in with what's there so this is ok
+	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_general );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )
+{
+    fill_me_in[LLMediaEntry::ALT_IMAGE_ENABLE_KEY] = mAltImageEnable->getValue();
+    fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
+    fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
+    fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
+    fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
+    fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
+    // XXX Don't send current URL!
+    //fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
+    fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
+    fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
+    fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
+    fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent )
+{
+	mParent = parent;
+};
diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h
new file mode 100644
index 0000000000000000000000000000000000000000..24678a3a070c0c4389a3d83870f4fb2ebb42e7a2
--- /dev/null
+++ b/indra/newview/llpanelmediasettingsgeneral.h
@@ -0,0 +1,89 @@
+/**
+ * @file llpanelmediasettingsgeneral.h
+ * @brief LLPanelMediaSettingsGeneral class definition
+ *
+ * $LicenseInfo:firstyear=2007&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_LLPANELMEDIAMEDIASETTINGSGENERAL_H
+#define LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
+
+#include "llpanel.h"
+
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLLineEditor;
+class LLSpinCtrl;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLFloaterMediaSettings;
+
+class LLPanelMediaSettingsGeneral : public LLPanel
+{
+public:
+	BOOL postBuild();
+	virtual void draw();
+	static void apply(void*);
+    void getValues(LLSD &fill_me_in);
+
+	LLPanelMediaSettingsGeneral();
+	~LLPanelMediaSettingsGeneral();
+
+	void setParent( LLFloaterMediaSettings* parent );
+	static void initValues( void* userdata, const LLSD& media_settings );
+	static void clearValues( void* userdata );
+	
+	void updateMediaPreview();
+	void updateCurrentURL();
+	
+	void onClose();
+
+protected:
+	LLFloaterMediaSettings* mParent;
+
+private:
+	void onBtnResetCurrentUrl();
+	static void onCommitHomeURL(LLUICtrl* ctrl, void *userdata );
+
+	LLComboBox* mControls;
+	LLCheckBoxCtrl* mAutoLoop;
+	LLCheckBoxCtrl* mFirstClick;
+	LLTextureCtrl* mMediaPreview;
+	LLCheckBoxCtrl* mAutoZoom;
+	LLCheckBoxCtrl* mAutoPlay;
+	LLCheckBoxCtrl* mAutoScale;
+	LLSpinCtrl* mWidthPixels;
+	LLSpinCtrl* mHeightPixels;
+	LLLineEditor* mHomeURL;
+	LLLineEditor* mCurrentURL;
+	LLCheckBoxCtrl* mAltImageEnable;
+	LLMediaCtrl* mPreviewMedia;
+};
+
+#endif  // LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d6a2677f4bf2209d6b61b27d017f2a739d569935
--- /dev/null
+++ b/indra/newview/llpanelmediasettingspermissions.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llpanelmediasettingspermissions.cpp
+ * @brief LLPanelMediaSettingsPermissions class implementation
+ *
+ * note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ * 'permissions' not changed to 'controls' since we don't want to change 
+ * shared files in server code and keeping everything the same seemed best.
+ *
+ * $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 "llviewerprecompiledheaders.h"
+
+#include "llpanelmediasettingspermissions.h"
+#include "llpanelcontents.h"
+#include "llcombobox.h"
+#include "llcheckboxctrl.h"
+#include "llspinctrl.h"
+#include "llurlhistory.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llmediaentry.h"
+#include "llnamebox.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() :
+    mPermsOwnerInteract( 0 ),
+    mPermsOwnerControl( 0 ),
+	mPermsGroupName( 0 ),
+    mPermsGroupInteract( 0 ),
+    mPermsGroupControl( 0 ),
+    mPermsWorldInteract( 0 ),
+    mPermsWorldControl( 0 )
+{
+    // build dialog from XML
+    LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_permissions.xml");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsPermissions::postBuild()
+{
+    // connect member vars with UI widgets
+    mPermsOwnerInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
+    mPermsOwnerControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
+    mPermsGroupInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
+    mPermsGroupControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
+    mPermsWorldInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
+    mPermsWorldControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
+
+	mPermsGroupName = getChild< LLNameBox >( "perms_group_name" );
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsPermissions::~LLPanelMediaSettingsPermissions()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void LLPanelMediaSettingsPermissions::draw()
+{
+	// housekeeping
+	LLPanel::draw();
+
+	childSetText("perms_group_name",LLStringUtil::null);
+	LLUUID group_id;
+	BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
+	if (groups_identical)
+	{
+		if(mPermsGroupName)
+		{
+			mPermsGroupName->setNameID(group_id, true);
+			mPermsGroupName->setEnabled(true);
+		};
+	}
+	else
+	{
+		if(mPermsGroupName)
+		{
+			mPermsGroupName->setNameID(LLUUID::null, TRUE);
+			mPermsGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, true);
+			mPermsGroupName->setEnabled(false);
+		};
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsPermissions::clearValues( void* userdata )
+{	
+	LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+	self->mPermsOwnerInteract->clear();
+	self->mPermsOwnerControl->clear();
+	self->mPermsGroupInteract ->clear();
+	self->mPermsGroupControl->clear();
+	self->mPermsWorldInteract ->clear();
+	self->mPermsWorldControl ->clear();
+//	mPermsGroupName ->setValue(0);
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings )
+{
+    LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+
+    std::string base_key( "" );
+    std::string tentative_key( "" );
+
+    struct 
+    {
+        std::string key_name;
+        LLUICtrl* ctrl_ptr;
+        std::string ctrl_type;
+
+    } data_set [] = 
+    { 
+        { LLPanelContents::PERMS_OWNER_INTERACT_KEY,    self->mPermsOwnerInteract,  "LLCheckBoxCtrl" },
+        { LLPanelContents::PERMS_OWNER_CONTROL_KEY,     self->mPermsOwnerControl,   "LLCheckBoxCtrl" },
+        { LLPanelContents::PERMS_GROUP_INTERACT_KEY,    self->mPermsGroupInteract,  "LLCheckBoxCtrl" },
+        { LLPanelContents::PERMS_GROUP_CONTROL_KEY,     self->mPermsGroupControl,   "LLCheckBoxCtrl" },
+        { LLPanelContents::PERMS_ANYONE_INTERACT_KEY,   self->mPermsWorldInteract,  "LLCheckBoxCtrl" },
+        { LLPanelContents::PERMS_ANYONE_CONTROL_KEY,    self->mPermsWorldControl,   "LLCheckBoxCtrl" },
+        { "", NULL , "" }
+    };
+
+    for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+    {
+        base_key = std::string( data_set[ i ].key_name );
+        tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+
+        // TODO: CP - I bet there is a better way to do this using Boost
+        if ( media_settings[ base_key ].isDefined() )
+        {
+            if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+            {
+				// the sense of the checkboxes changed and it made sense
+				// to just reverse their sense back again here and avoid 
+				// changing server code.
+                static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+                    setValue( ! media_settings[ base_key ].asBoolean() );
+            }
+            else
+            if ( data_set[ i ].ctrl_type == "LLComboBox" )
+                static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
+                    setCurrentByIndex( media_settings[ base_key ].asInteger() );
+
+            data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+        };
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsPermissions::apply( void* userdata )
+{
+    LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
+
+    // build LLSD Fragment
+    LLSD media_data_permissions;
+    self->getValues(media_data_permissions);
+
+    // this merges contents of LLSD passed in with what's there so this is ok
+    LLSelectMgr::getInstance()->selectionSetMediaData( media_data_permissions );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in )
+{
+    // *NOTE: For some reason, gcc does not like these symbol references in the 
+    // expressions below (inside the static_casts).  I have NO idea why :(.
+    // For some reason, assigning them to const temp vars here fixes the link
+    // error.  Bizarre.
+    const U8 none = LLMediaEntry::PERM_NONE;
+    const U8 owner = LLMediaEntry::PERM_OWNER;
+    const U8 group = LLMediaEntry::PERM_GROUP;
+    const U8 anyone = LLMediaEntry::PERM_ANYONE;
+    const LLSD::Integer control = static_cast<LLSD::Integer>(
+        (mPermsOwnerControl->getValue() ? none : owner ) |
+        (mPermsGroupControl->getValue() ? none : group ) |
+        (mPermsWorldControl->getValue() ? none : anyone ));
+    const LLSD::Integer interact = static_cast<LLSD::Integer>(
+        (mPermsOwnerInteract->getValue() ? none : owner ) |
+        (mPermsGroupInteract->getValue() ? none : group ) |
+        (mPermsWorldInteract->getValue() ? none : anyone ));
+    fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control;
+    fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact;
+}
diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce293e07b9126fa7f19d7c29ff977ab08dd70f27
--- /dev/null
+++ b/indra/newview/llpanelmediasettingspermissions.h
@@ -0,0 +1,71 @@
+/**
+ * @file llpanelmediasettingspermissions.h
+ * @brief LLPanelMediaSettingsPermissions class definition
+ *
+ * note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ * 'permissions' not changed to 'controls' since we don't want to change 
+ * shared files in server code and keeping everything the same seemed best.
+ *
+ * $LicenseInfo:firstyear=2007&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_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
+#define LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+
+class LLComboBox;
+class LLCheckBoxCtrl;
+class LLNameBox;
+
+class LLPanelMediaSettingsPermissions : public LLPanel
+{
+	public:
+		BOOL postBuild();
+		virtual void draw();
+		static void apply(void*);
+        void getValues(LLSD &fill_me_in);
+
+		LLPanelMediaSettingsPermissions();
+		~LLPanelMediaSettingsPermissions();
+
+		static void initValues( void* userdata, const LLSD& media_settings );
+		static void clearValues( void* userdata );
+
+	private:
+        LLCheckBoxCtrl* mPermsOwnerInteract;
+		LLCheckBoxCtrl* mPermsOwnerControl;
+		LLNameBox* mPermsGroupName;
+		LLCheckBoxCtrl* mPermsGroupInteract;
+		LLCheckBoxCtrl* mPermsGroupControl;
+		LLCheckBoxCtrl* mPermsWorldInteract;
+		LLCheckBoxCtrl* mPermsWorldControl;
+};
+
+#endif  // LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4eee82aa9fd4873ac80c57bfd499c9e4faaa5d5
--- /dev/null
+++ b/indra/newview/llpanelmediasettingssecurity.cpp
@@ -0,0 +1,233 @@
+/**
+ * @file llpanelmediasettingssecurity.cpp
+ * @brief LLPanelMediaSettingsSecurity class implementation
+ *
+ * $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 "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llpanelmediasettingssecurity.h"
+#include "llpanelcontents.h"
+#include "llcheckboxctrl.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llmediaentry.h"
+#include "llfloaterwhitelistentry.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity()
+{
+	// build dialog from XML
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml");
+	mCommitCallbackRegistrar.add("Media.whitelistAdd",		boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this));
+	mCommitCallbackRegistrar.add("Media.whitelistDelete",	boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));	
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLPanelMediaSettingsSecurity::postBuild()
+{
+	mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY );
+	mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY );
+
+	childSetAction("whitelist_add", onBtnAdd, this);
+	childSetAction("whitelist_del", onBtnDel, this);
+
+	setDefaultBtn("whitelist_add");
+
+	return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// 
+void LLPanelMediaSettingsSecurity::draw()
+{
+	// housekeeping
+	LLPanel::draw();
+
+	// if list is empty, disable DEL button and checkbox to enable use of list
+	if ( mWhiteListList->isEmpty() )
+	{
+		childSetEnabled( "whitelist_del", false );
+		childSetEnabled( LLMediaEntry::WHITELIST_KEY, false );
+		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, false );
+	}
+	else
+	{
+		childSetEnabled( "whitelist_del", true );
+		childSetEnabled( LLMediaEntry::WHITELIST_KEY, true );
+		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, true );
+	};
+
+	// if nothing is selected, disable DEL button
+	if ( mWhiteListList->getSelectedValue().asString().empty() )
+	{
+		childSetEnabled( "whitelist_del", false );
+	}
+	else
+	{
+		childSetEnabled( "whitelist_del", true );
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings )
+{
+	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+	std::string base_key( "" );
+	std::string tentative_key( "" );
+
+	struct 
+	{
+		std::string key_name;
+		LLUICtrl* ctrl_ptr;
+		std::string ctrl_type;
+
+	} data_set [] = 
+	{
+		{ LLMediaEntry::WHITELIST_ENABLE_KEY,	self->mEnableWhiteList,		"LLCheckBoxCtrl" },
+		{ LLMediaEntry::WHITELIST_KEY,			self->mWhiteListList,		"LLScrollListCtrl" },
+		{ "", NULL , "" }
+	};
+
+	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
+	{
+		base_key = std::string( data_set[ i ].key_name );
+        tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
+
+		// TODO: CP - I bet there is a better way to do this using Boost
+		if ( media_settings[ base_key ].isDefined() )
+		{
+			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
+			{
+				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
+					setValue( media_settings[ base_key ].asBoolean() );
+			}
+			else
+			if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" )
+			{
+				// get control 
+				LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );
+				list->deleteAllItems();
+
+				// points to list of white list URLs
+				LLSD url_list = media_settings[ base_key ];
+
+				// iterate over them and add to scroll list
+				LLSD::array_iterator iter = url_list.beginArray();
+				while( iter != url_list.endArray() )
+				{
+					// TODO: is iter guaranteed to be valid here?
+					std::string url = *iter;
+					list->addSimpleElement( url );
+					++iter;
+				};
+			};
+
+			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
+		};
+	};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static 
+void LLPanelMediaSettingsSecurity::clearValues( void* userdata )
+{
+	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+	self->mEnableWhiteList->clear();
+	self->mWhiteListList->deleteAllItems();
+}
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::apply( void* userdata )
+{
+	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+	// build LLSD Fragment
+	LLSD media_data_security;
+	self->getValues(media_data_security);
+	// this merges contents of LLSD passed in with what's there so this is ok
+	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_security );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in )
+{
+    fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = mEnableWhiteList->getValue();
+
+    // iterate over white list and extract items
+    std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData();
+    std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin();
+    fill_me_in[LLMediaEntry::WHITELIST_KEY].clear();
+    while( iter != white_list_items.end() )
+    {
+        std::string white_list_url = (*iter)->getValue().asString();
+        fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( white_list_url );
+        ++iter;
+    };
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::addWhiteListItem(const std::string& url)
+{
+	mWhiteListList->addSimpleElement( url );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata )
+{
+	LLFloaterReg::showInstance("whitelist_entry");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata )
+{
+	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
+
+	self->mWhiteListList->deleteSelectedItems();
+}
diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h
new file mode 100644
index 0000000000000000000000000000000000000000..d77509897d867e14124df2f1523416bee89a18d7
--- /dev/null
+++ b/indra/newview/llpanelmediasettingssecurity.h
@@ -0,0 +1,64 @@
+/**
+ * @file llpanelmediasettingssecurity.h
+ * @brief LLPanelMediaSettingsSecurity class definition
+ *
+ * $LicenseInfo:firstyear=2007&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_LLPANELMEDIAMEDIASETTINGSSECURITY_H
+#define LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
+
+#include "llpanel.h"
+
+class LLCheckBoxCtrl;
+class LLScrollListCtrl;
+
+class LLPanelMediaSettingsSecurity : public LLPanel
+{
+	public:
+		BOOL postBuild();
+		virtual void draw();
+		static void apply(void*);
+        void getValues(LLSD &fill_me_in);
+
+		LLPanelMediaSettingsSecurity();
+		~LLPanelMediaSettingsSecurity();
+
+		static void initValues( void* userdata, const LLSD& media_settings );
+		static void clearValues( void* userdata );
+		void addWhiteListItem(const std::string& url);
+
+	private:
+		LLCheckBoxCtrl* mEnableWhiteList;
+		LLScrollListCtrl* mWhiteListList;
+
+		static void onBtnAdd(void*);
+		static void onBtnDel(void*);
+};
+
+#endif  // LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6a41b6feb98dcc7b3ce749a71231df1cb1f59fd8..b2a0a01005a6d06f82d0d80c2115ada7f2f90133 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -60,11 +60,8 @@
 #include "llvoiceclient.h"
 #include "llworld.h"
 
-using namespace LLOldEvents;
-
 #define FRIEND_LIST_UPDATE_TIMEOUT	0.5
 #define NEARBY_LIST_UPDATE_INTERVAL 1
-#define RECENT_LIST_UPDATE_DELAY	1
 
 static const std::string NEARBY_TAB_NAME	= "nearby_panel";
 static const std::string FRIENDS_TAB_NAME	= "friends_panel";
@@ -102,7 +99,7 @@ static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
 class LLPanelPeople::Updater
 {
 public:
-	typedef boost::function<bool(U32)> callback_t;
+	typedef boost::function<void()> callback_t;
 	Updater(callback_t cb)
 	: mCallback(cb)
 	{
@@ -112,16 +109,6 @@ class LLPanelPeople::Updater
 	{
 	}
 
-	/**
-	 * Force the list updates.
-	 * 
-	 * This may start repeated updates until all names are complete.
-	 */
-	virtual void forceUpdate()
-	{
-		updateList();
-	}
-
 	/**
 	 * Activate/deactivate updater.
 	 *
@@ -130,9 +117,9 @@ class LLPanelPeople::Updater
 	virtual void setActive(bool) {}
 
 protected:
-	bool updateList(U32 mask = 0)
+	void updateList()
 	{
-		return mCallback(mask);
+		mCallback();
 	}
 
 	callback_t		mCallback;
@@ -147,6 +134,11 @@ class LLAvatarListUpdater : public LLPanelPeople::Updater, public LLEventTimer
 	{
 		mEventTimer.stop();
 	}
+
+	virtual BOOL tick() // from LLEventTimer
+	{
+		return FALSE;
+	}
 };
 
 /**
@@ -178,13 +170,6 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 		LLAvatarTracker::instance().removeObserver(this);
 	}
 
-	/*virtual*/ void forceUpdate()
-	{
-		// Perform updates until all names are loaded.
-		if (!updateList(LLFriendObserver::ADD))
-			changed(LLFriendObserver::ADD);
-	}
-
 	/*virtual*/ void changed(U32 mask)
 	{
 		// events can arrive quickly in bulk - we need not process EVERY one of them -
@@ -198,12 +183,12 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 
 	/*virtual*/ BOOL tick()
 	{
-		if (updateList(mMask))
-		{
-			// Got all names, stop updates.
-			mEventTimer.stop();
-			mMask = 0;
-		}
+		if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
+			updateList();
+
+		// Stop updates.
+		mEventTimer.stop();
+		mMask = 0;
 
 		return FALSE;
 	}
@@ -329,68 +314,9 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
 
 public:
 	LLRecentListUpdater(callback_t cb)
-	:	LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
-	{
-		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
-	}
-
-private:
-	/*virtual*/ void forceUpdate()
-	{
-		onRecentPeopleChanged();
-	}
-	
-	/*virtual*/ BOOL tick()
-	{
-		// Update the list until we get all the names. 
-		if (updateList())
-		{
-			// Got all names, stop updates.
-			mEventTimer.stop();
-		}
-
-		return FALSE;
-	}
-
-	void onRecentPeopleChanged()
-	{
-		if (!updateList())
-		{
-			// Some names are incomplete, schedule another update.
-			mEventTimer.start();
-		}
-	}
-};
-
-/**
- * Updates the group list on events from LLAgent.
- */
-class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
-{
-	LOG_CLASS(LLGroupListUpdater);
-
-public:
-	LLGroupListUpdater(callback_t cb)
-	:	LLPanelPeople::Updater(cb)
-	{
-		gAgent.addListener(this, "new group");
-	}
-
-	~LLGroupListUpdater()
+	:	LLAvatarListUpdater(cb, 0)
 	{
-		gAgent.removeListener(this);
-	}
-
-	/*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		// Why is "new group" sufficient?
-		if (event->desc() == "new group")
-		{
-			updateList();
-			return true;
-		}
-
-		return false;
+		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
 	}
 };
 
@@ -404,12 +330,12 @@ LLPanelPeople::LLPanelPeople()
 		mOnlineFriendList(NULL),
 		mAllFriendList(NULL),
 		mNearbyList(NULL),
-		mRecentList(NULL)
+		mRecentList(NULL),
+		mGroupList(NULL)
 {
-	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
+	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));
 	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));
 	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));
-	mGroupListUpdater  = new LLGroupListUpdater	(boost::bind(&LLPanelPeople::updateGroupList,	this));
 }
 
 LLPanelPeople::~LLPanelPeople()
@@ -417,7 +343,6 @@ LLPanelPeople::~LLPanelPeople()
 	delete mNearbyListUpdater;
 	delete mFriendListUpdater;
 	delete mRecentListUpdater;
-	delete mGroupListUpdater;
 
 	LLView::deleteViewByHandle(mGroupPlusMenuHandle);
 	LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
@@ -512,7 +437,7 @@ BOOL LLPanelPeople::postBuild()
 	buttonSetAction("share_btn",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
 
 	getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked,		this));
-	getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked,		this));
+	getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked,			this));
 	getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked,		this));
 	getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked,		this));
 
@@ -547,137 +472,71 @@ BOOL LLPanelPeople::postBuild()
 	if(recent_view_sort)
 		mRecentViewSortMenuHandle  = recent_view_sort->getHandle();
 
-
-
-	// Perform initial update.
-	mFriendListUpdater->forceUpdate();
-	mNearbyListUpdater->forceUpdate();
-	mGroupListUpdater->forceUpdate();
-	mRecentListUpdater->forceUpdate();
-
 	// call this method in case some list is empty and buttons can be in inconsistent state
 	updateButtons();
 
 	return TRUE;
 }
 
-void LLPanelPeople::applyFilterToTab(const std::string& tab_name)
-{
-	if (tab_name == FRIENDS_TAB_NAME) // this tab has two lists
-		filterFriendList();
-	else if (tab_name == NEARBY_TAB_NAME)
-		filterNearbyList();
-	else if (tab_name == RECENT_TAB_NAME)
-		filterRecentList();
-	else if (tab_name == GROUP_TAB_NAME)
-		updateGroupList();
-}
-
-bool LLPanelPeople::updateFriendList(U32 changed_mask)
+void LLPanelPeople::updateFriendList()
 {
-	// Refresh names.
-	if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
-	{
-		// get all buddies we know about
-		const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
-		LLAvatarTracker::buddy_map_t all_buddies;
-		av_tracker.copyBuddyList(all_buddies);
-
-		// *TODO: it's suboptimal to rebuild the whole lists on online status change.
+	if (!mOnlineFriendList || !mAllFriendList)
+		return;
 
-		// save them to the online and all friends vectors
-		mOnlineFriendVec.clear();
-		mAllFriendVec.clear();
+	// get all buddies we know about
+	const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+	LLAvatarTracker::buddy_map_t all_buddies;
+	av_tracker.copyBuddyList(all_buddies);
 
-		LLFriendCardsManager::folderid_buddies_map_t listMap;
+	// save them to the online and all friends vectors
+	LLAvatarList::uuid_vector_t& online_friendsp = mOnlineFriendList->getIDs();
+	LLAvatarList::uuid_vector_t& all_friendsp = mAllFriendList->getIDs();
 
-		// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
-		LLFriendCardsManager::instance().collectFriendsLists(listMap);
-		if (listMap.size() > 0)
-		{
-			lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
-			mAllFriendVec = listMap.begin()->second;
-		}
-		else
-		{
-			lldebugs << "Friends Cards were not found" << llendl;
-		}
+	all_friendsp.clear();
+	online_friendsp.clear();
 
-		LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
-		for (; buddy_it != all_buddies.end(); ++buddy_it)
-		{
-			LLUUID buddy_id = buddy_it->first;
-			if (av_tracker.isBuddyOnline(buddy_id))
-				mOnlineFriendVec.push_back(buddy_id);
-		}
+	LLFriendCardsManager::folderid_buddies_map_t listMap;
 
-		return filterFriendList();
+	// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
+	LLFriendCardsManager::instance().collectFriendsLists(listMap);
+	if (listMap.size() > 0)
+	{
+		lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
+		all_friendsp = listMap.begin()->second;
+	}
+	else
+	{
+		lldebugs << "Friends Cards were not found" << llendl;
 	}
 
-	return true;
-}
-
-bool LLPanelPeople::updateNearbyList()
-{
-	LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
-	filterNearbyList();
-
-	return true;
-}
-
-bool LLPanelPeople::updateRecentList()
-{
-	LLRecentPeople::instance().get(mRecentVec);
-	filterRecentList();
-
-	return true;
-}
-
-bool LLPanelPeople::updateGroupList()
-{
-	if (!mGroupList)
-		return true; // there's no point in further updates
+	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+	for (; buddy_it != all_buddies.end(); ++buddy_it)
+	{
+		LLUUID buddy_id = buddy_it->first;
+		if (av_tracker.isBuddyOnline(buddy_id))
+			online_friendsp.push_back(buddy_id);
+	}
 
-	bool have_names = mGroupList->update(mFilterSubString);
-	updateButtons();
-	return have_names;
+	mOnlineFriendList->setDirty();
+	mAllFriendList->setDirty();
 }
 
-bool LLPanelPeople::filterFriendList()
+void LLPanelPeople::updateNearbyList()
 {
-	if (!mOnlineFriendList || !mAllFriendList)
-		return true; // there's no point in further updates
-
-	// We must always update Friends list to clear the latest removed friend.
-	bool have_names =
-			mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
-			mAllFriendList->update(mAllFriendVec, mFilterSubString);
-
-
-	updateButtons();
-	return have_names;
-}
+	if (!mNearbyList)
+		return;
 
-bool LLPanelPeople::filterNearbyList()
-{
-	bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
-	updateButtons();
-	return have_names;
+	LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+	mNearbyList->setDirty();
 }
 
-bool LLPanelPeople::filterRecentList()
+void LLPanelPeople::updateRecentList()
 {
 	if (!mRecentList)
-		return true;
-
-	if (mRecentVec.size() > 0)
-	{
-		bool updated = mRecentList->update(mRecentVec, mFilterSubString);
-		updateButtons();
-		return updated;
-	}
+		return;
 
-	return true;
+	LLRecentPeople::instance().get(mRecentList->getIDs());
+	mRecentList->setDirty();
 }
 
 void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -846,16 +705,19 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
 	LLStringUtil::toUpper(mFilterSubString);
 	LLStringUtil::trimHead(mFilterSubString);
 
-	// Apply new filter to current tab.
-	applyFilterToTab(getActiveTabName());
+	// Apply new filter.
+	mNearbyList->setNameFilter(mFilterSubString);
+	mOnlineFriendList->setNameFilter(mFilterSubString);
+	mAllFriendList->setNameFilter(mFilterSubString);
+	mRecentList->setNameFilter(mFilterSubString);
+	mGroupList->setNameFilter(mFilterSubString);
 }
 
 void LLPanelPeople::onTabSelected(const LLSD& param)
 {
 	std::string tab_name = getChild<LLPanel>(param.asString())->getName();
 	mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
-	applyFilterToTab(tab_name);
-	// No need to call updateButtons() because applyFilterToTab() does that.
+	updateButtons();
 
 	if (GROUP_TAB_NAME == tab_name)
 		mFilterEditor->setLabel(getString("groups_filter_label"));
@@ -960,17 +822,6 @@ void LLPanelPeople::onAvatarPicked(
 		LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
 }
 
-bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
-{
-	bool have_names = updateFriendList(changed_mask);
-
-	// Update online status in the Recent tab.
-	// *TODO: isn't it too much to update the whole list?
-//	updateRecentList(); // mantipov: seems online status should be supported by LLAvatarListItem itself.
-
-	return have_names;
-}
-
 void LLPanelPeople::onGroupPlusButtonClicked()
 {
 	LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 8cd3cc7febafed36a32ff70dc20264e7bdfdcc9e..de27814388b9630b189e44ac1ebb8c48a46b9443 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -58,15 +58,10 @@ class LLPanelPeople : public LLPanel
 
 private:
 	// methods indirectly called by the updaters
-	bool					updateFriendList(U32 changed_mask);
-	bool					updateNearbyList();
-	bool					updateRecentList();
-	bool					updateGroupList();
-
-	bool					filterFriendList();
-	bool					filterNearbyList();
-	bool					filterRecentList();
-	void					applyFilterToTab(const std::string& tab_name);
+	void					updateFriendList();
+	void					updateNearbyList();
+	void					updateRecentList();
+
 	void					updateButtons();
 	const std::string&		getActiveTabName() const;
 	LLUUID					getCurrentItemID() const;
@@ -110,7 +105,6 @@ class LLPanelPeople : public LLPanel
 	void					onRecentViewSortMenuItemClicked(const LLSD& userdata);
 
 	// misc callbacks
-	bool					onFriendListUpdate(U32 changed_mask);
 	static void				onAvatarPicked(
 								const std::vector<std::string>& names,
 								const std::vector<LLUUID>& ids,
@@ -135,21 +129,8 @@ class LLPanelPeople : public LLPanel
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
-	Updater*				mGroupListUpdater;
 
 	std::string				mFilterSubString;
-
-	// The vectors below contain up-to date avatar lists
-	// for the corresponding tabs.
-	// When the user enters a filter, it gets applied
-	// to all the vectors and the result is shown in the tabs.
-	// We don't need to have such a vector for the groups tab
-	// since re-fetching the groups list is always fast.
-	typedef std::vector<LLUUID> uuid_vector_t;
-	uuid_vector_t			mNearbyVec;
-	uuid_vector_t			mOnlineFriendVec;
-	uuid_vector_t			mAllFriendVec;
-	uuid_vector_t			mRecentVec;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 42185d28e5c4980d389d54660c0254172aa28645..5df3d4f1d631c59ce86f5796a127017b0249ecb5 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -39,8 +39,10 @@
 #include "message.h"
 #include "llagent.h"
 #include "llbutton.h"
+#include "lllineeditor.h"
 #include "llparcel.h"
 #include "llviewerparcelmgr.h"
+#include "lltexteditor.h"
 #include "lltexturectrl.h"
 #include "lluiconstants.h"
 #include "llworldmap.h"
@@ -73,7 +75,8 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
 	mPickId(LLUUID::null),
 	mCreatorId(LLUUID::null),
 	mDataReceived(FALSE),
-	mIsPickNew(false)
+	mIsPickNew(false),
+	mLocationChanged(false)
 {
 	if (edit_mode)
 	{
@@ -123,6 +126,16 @@ BOOL LLPanelPick::postBuild()
 
 	if (mEditMode)
 	{
+		enableSaveButton(FALSE);
+
+		mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
+		LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
+		line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL);
+		
+		LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
+		text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
 		childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
 		childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
 		childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
@@ -287,6 +300,26 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
 	updateButtons();
 }
 
+void LLPanelPick::onPickChanged(LLUICtrl* ctrl)
+{
+	if(mLocationChanged)
+	{
+		// Pick was enabled in onClickSet
+		return;
+	}
+
+	if( mSnapshotCtrl->isDirty()
+		|| getChild<LLLineEditor>("pick_name")->isDirty()
+		|| getChild<LLTextEditor>("pick_desc")->isDirty() )
+	{
+		enableSaveButton(TRUE);
+	}
+	else
+	{
+		enableSaveButton(FALSE);
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////
 // PROTECTED AREA
 //////////////////////////////////////////////////////////////////////////
@@ -466,6 +499,9 @@ void LLPanelPick::onClickSet()
 		mSimName = parcel->getName();
 	}
 	setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
+
+	mLocationChanged = true;
+	enableSaveButton(TRUE);
 }
 
 // static
@@ -552,3 +588,12 @@ void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
 
 	//*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
 }
+
+void LLPanelPick::enableSaveButton(bool enable)
+{
+	if(!mEditMode)
+	{
+		return;
+	}
+	childSetEnabled(XML_BTN_SAVE, enable);
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 7ce58b59afd2856eaed42622e80237c03879c193..82cba72bc48b6b8b30e23b2904c046c32d26c18a 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -74,6 +74,8 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	// switches the panel to either View or Edit mode
 	void setEditMode(BOOL edit_mode);
 
+	void onPickChanged(LLUICtrl* ctrl);
+
 	// because this panel works in two modes (edit/view) we are  
 	// free from managing two panel for editing and viewing picks and so
 	// are free from controlling switching between them in the parent panel (e.g. Me Profile)
@@ -128,6 +130,8 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	void onClickSave();
 	void onClickCancel();
 
+	void enableSaveButton(bool enable);
+
 protected:
 	BOOL mEditMode;
 	LLTextureCtrl*	mSnapshotCtrl;
@@ -146,6 +150,7 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	std::string mLocation;
 
 	commit_callback_t mBackCb;
+	bool mLocationChanged;
 };
 
 #endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 93317e613f4df3c75885b7da952553c5b29c5c32..e74afba25acdba3fbf6b633a2377f42c9b834afa 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -126,8 +126,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 				mPicksList->addItem(picture, pick_value);
 
 				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
-				picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
-				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
 				picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 			}
 
@@ -260,8 +259,10 @@ void LLPanelPicks::onClickMap()
 }
 
 
-void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
 {
+	updateButtons();
+
 	if (mPopupMenu)
 	{
 		mPopupMenu->buildDrawLabels();
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 27a21305b3f6b4779bf4f368958b08aa52e443af..7ebdc3089c8d9e7b46b75354b70ce303da2d3f22 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -100,7 +100,7 @@ class LLPanelPicks
 	void updateButtons();
 
 	virtual void onDoubleClickItem(LLUICtrl* item);
-	virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
+	virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
 
 	LLPanelProfile* getProfilePanel();
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 4e070df7eb6e6e26770fb591749a5a454b93fc31..80ecc95afb32592e9a64863aead67e3959c67893 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -337,7 +337,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
 		LLStringUtil::trimHead(mFilterSubString);
 
 		if (mActivePanel)
-		mActivePanel->onSearchEdit(mFilterSubString);
+			mActivePanel->onSearchEdit(mFilterSubString);
 	}
 }
 
@@ -386,7 +386,7 @@ void LLPanelPlaces::onTeleportButtonClicked()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->onTeleport();
+			mActivePanel->onTeleport();
 	}
 }
 
@@ -432,7 +432,7 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->onShowOnMap();
+			mActivePanel->onShowOnMap();
 	}
 }
 
@@ -510,7 +510,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
 			addChild(mPickPanel);
 
 			mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
-	}
+		}
 
 		togglePickPanel(TRUE);
 
@@ -733,7 +733,7 @@ void LLPanelPlaces::updateVerbs()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->updateVerbs();
+			mActivePanel->updateVerbs();
 	}
 }
 
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index f6672d9c8b68f93a4dd4ce3da95b69a8e6954cc2..9754094aaa9f1feb9121417df0ce7725341ab11f 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -42,11 +42,15 @@
 #include "llaccordionctrltab.h"
 #include "llflatlistview.h"
 #include "lltextbox.h"
+#include "llviewermenu.h"
+#include "llviewerinventory.h"
+#include "lllandmarkactions.h"
+#include "llclipboard.h"
 
 class LLTeleportHistoryFlatItem : public LLPanel
 {
 public:
-	LLTeleportHistoryFlatItem(S32 index, const std::string &region_name);
+	LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name);
 	virtual ~LLTeleportHistoryFlatItem() {};
 
 	virtual BOOL postBuild();
@@ -57,18 +61,23 @@ class LLTeleportHistoryFlatItem : public LLPanel
 
 	void onMouseEnter(S32 x, S32 y, MASK mask);
 	void onMouseLeave(S32 x, S32 y, MASK mask);
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	static void showPlaceInfoPanel(S32 index);
 private:
 	void onInfoBtnClick();
 
 	LLButton* mInfoBtn;
+	LLTeleportHistoryPanel::ContextMenu *mContextMenu;
 
 	S32 mIndex;
 	std::string mRegionName;
 };
 
-LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, const std::string &region_name)
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name)
 :	LLPanel(),
 	mIndex(index),
+	mContextMenu(context_menu),
 	mRegionName(region_name)
 {
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml");
@@ -109,15 +118,105 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
 	LLPanel::onMouseLeave(x, y, mask);
 }
 
-void LLTeleportHistoryFlatItem::onInfoBtnClick()
+// virtual
+BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (mContextMenu)
+		mContextMenu->show(this, mIndex, x, y);
+
+	return LLPanel::handleRightMouseDown(x, y, mask);
+}
+
+void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index)
 {
 	LLSD params;
-	params["id"] = mIndex;
+	params["id"] = index;
 	params["type"] = "teleport_history";
 
 	LLSideTray::getInstance()->showPanel("panel_places", params);
 }
 
+void LLTeleportHistoryFlatItem::onInfoBtnClick()
+{
+	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+LLTeleportHistoryPanel::ContextMenu::ContextMenu() :
+	mMenu(NULL)
+{
+}
+
+void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y)
+{
+	if (mMenu)
+	{
+		//preventing parent (menu holder) from deleting already "dead" context menus on exit
+		LLView* parent = mMenu->getParent();
+		if (parent)
+		{
+			parent->removeChild(mMenu);
+			mMenu->setParent(NULL);
+		}
+		delete mMenu;
+	}
+
+	mIndex = index;
+	mMenu = createMenu();
+
+	LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos(
+		LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos);
+
+	mMenu->setItemEnabled("Make Landmark", !landmark || landmark->getUUID().isNull());
+
+	mMenu->show(x, y);
+	LLMenuGL::showPopup(spawning_view, mMenu, x, y);
+}
+
+LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
+{
+	// set up the callbacks for all of the avatar menu items
+	// (N.B. callbacks don't take const refs as mID is local scope)
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+	registrar.add("TeleportHistory.Teleport",	boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
+	registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
+	registrar.add("TeleportHistory.Copy",		boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this));
+	registrar.add("TeleportHistory.MakeLandmark",	boost::bind(&LLTeleportHistoryPanel::ContextMenu::onMakeLandmark, this));
+
+	// create the context menu from the XUI
+	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+		"menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onTeleport()
+{
+	LLTeleportHistoryStorage::getInstance()->goToItem(mIndex);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onInfo()
+{
+	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+//static
+void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
+{
+	gClipboard.copyFromString(utf8str_to_wstring(slurl));
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onCopy()
+{
+	LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
+	LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
+		boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onMakeLandmark()
+{
+	//FIXME: it creates landmark for current agent positon, not for the global position of item of teleport history
+	LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+}
+
 // Not yet implemented; need to remove buildPanel() from constructor when we switch
 //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
 
@@ -126,6 +225,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
 		mFilterSubString(LLStringUtil::null),
 		mTeleportHistory(NULL),
 		mHistoryAccordion(NULL),
+		mAccordionTabMenu(NULL),
 		mLastSelectedScrollList(NULL)
 {
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml");
@@ -153,6 +253,8 @@ BOOL LLTeleportHistoryPanel::postBuild()
 			if (dynamic_cast<LLAccordionCtrlTab*>(*iter))
 			{
 				LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter;
+				tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4));
+
 				mItemContainers.put(tab);
 
 				LLFlatListView* fl = getFlatListViewFromTab(tab);
@@ -306,12 +408,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
 					
 					if (curr_tab <= tabs_cnt - 4)
 					{
-					curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
+						curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
 					}
 					else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
 					{
 						curr_date =  LLDate::now();
-					curr_date.split(&curr_year, &curr_month, &curr_day);
+						curr_date.split(&curr_year, &curr_month, &curr_day);
 						curr_month--;
 						if (0 == curr_month)
 						{
@@ -354,7 +456,7 @@ void LLTeleportHistoryPanel::showTeleportHistory()
 
 		if (curr_flat_view)
 		{			
-			curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, (*iter).mTitle));
+			curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle));
 		}
 
 		index--;
@@ -376,7 +478,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
 	S32 tabs_cnt = mItemContainers.size();
 
 	for (S32 n = 0; n < tabs_cnt; n++)
-		{
+	{
 		LLAccordionCtrlTab* tab = mItemContainers.get(n);
 
 		if (!tab->getVisible())
@@ -390,7 +492,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
 			continue;
 
 		flv->resetSelection(true);
-		}
+	}
 
 	updateVerbs();
 }
@@ -411,6 +513,56 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data)
 	LLSideTray::getInstance()->showPanel("panel_places", key);*/
 }
 
+void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask)
+{
+	LLAccordionCtrlTab *tab = (LLAccordionCtrlTab *) view;
+
+	// If click occurred below the header, don't show this menu
+	if (y < tab->getRect().getHeight() - tab->getHeaderHeight() - tab->getPaddingBottom())
+		return;
+
+	if (mAccordionTabMenu)
+	{
+		//preventing parent (menu holder) from deleting already "dead" context menus on exit
+		LLView* parent = mAccordionTabMenu->getParent();
+		if (parent)
+		{
+			parent->removeChild(mAccordionTabMenu);
+			mAccordionTabMenu->setParent(NULL);
+		}
+		delete mAccordionTabMenu;
+	}
+
+	// set up the callbacks for all of the avatar menu items
+	// (N.B. callbacks don't take const refs as mID is local scope)
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+	registrar.add("TeleportHistory.TabOpen",	boost::bind(&LLTeleportHistoryPanel::onAccordionTabOpen, this, tab));
+	registrar.add("TeleportHistory.TabClose",	boost::bind(&LLTeleportHistoryPanel::onAccordionTabClose, this, tab));
+
+	// create the context menu from the XUI
+	mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+		"menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+
+	mAccordionTabMenu->setItemVisible("TabOpen", !tab->isExpanded() ? true : false);
+	mAccordionTabMenu->setItemVisible("TabClose", tab->isExpanded() ? true : false);
+
+	mAccordionTabMenu->show(x, y);
+	LLMenuGL::showPopup(tab, mAccordionTabMenu, x, y);
+}
+
+void LLTeleportHistoryPanel::onAccordionTabOpen(LLAccordionCtrlTab *tab)
+{
+	tab->setDisplayChildren(true);
+	mHistoryAccordion->arrange();
+}
+
+void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)
+{
+	tab->setDisplayChildren(false);
+	mHistoryAccordion->arrange();
+}
+
 LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTab *tab)
 {
 	for (child_list_const_iter_t iter = tab->beginChild(); iter != tab->endChild(); iter++)
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 66187e69c65b947c8e3f89f3d5d3c7813babd650..ebba25cfa5f7f4541d4166379bb29abb911af92f 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -37,6 +37,7 @@
 
 #include "llpanelplacestab.h"
 #include "llteleporthistory.h"
+#include "llmenugl.h"
 
 class LLTeleportHistoryStorage;
 class LLAccordionCtrl;
@@ -46,6 +47,25 @@ class LLFlatListView;
 class LLTeleportHistoryPanel : public LLPanelPlacesTab
 {
 public:
+	class ContextMenu
+	{
+	public:
+		ContextMenu();
+		void show(LLView* spawning_view, S32 index, S32 x, S32 y);
+		
+	private:
+		LLContextMenu* createMenu();
+		void onTeleport();
+		void onInfo();
+		void onCopy();
+		void onMakeLandmark();
+
+		static void gotSLURLCallback(const std::string& slurl);
+		
+		LLContextMenu* mMenu;
+		S32 mIndex;
+	};
+
 	LLTeleportHistoryPanel();
 	virtual ~LLTeleportHistoryPanel();
 
@@ -59,6 +79,9 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab
 private:
 
 	static void onDoubleClickItem(void* user_data);
+	void onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask);
+	void onAccordionTabOpen(LLAccordionCtrlTab *tab);
+	void onAccordionTabClose(LLAccordionCtrlTab *tab);
 	void showTeleportHistory();
 	void handleItemSelect(LLFlatListView* );
 	LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
@@ -70,6 +93,9 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab
 
 	typedef LLDynamicArray<LLAccordionCtrlTab*> item_containers_t;
 	item_containers_t mItemContainers;
+
+	ContextMenu mContextMenu;
+	LLContextMenu*			mAccordionTabMenu;
 };
 
 #endif //LL_LLPANELTELEPORTHISTORY_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 0ecdec65d6d79a63a87ce627a962a2ccea69b67f..19bb60b237fe8f3de20c41c0334c9d0c7eed96ba 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -44,6 +44,7 @@
 #include "llinventorymodel.h"
 #include "llkeyboard.h"
 #include "lllineeditor.h"
+#include "llhelp.h"
 
 #include "llresmgr.h"
 #include "llscrollbar.h"
@@ -103,7 +104,7 @@ const std::string HELLO_LSL =
 	"        llSay(0, \"Touched.\");\n"
 	"    }\n"
 	"}\n";
-const std::string HELP_LSL_URL = "http://wiki.secondlife.com/wiki/LSL_Portal";
+const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal";
 
 const std::string DEFAULT_SCRIPT_NAME = "New Script"; // *TODO:Translate?
 const std::string DEFAULT_SCRIPT_DESC = "(No Description)"; // *TODO:Translate?
@@ -264,7 +265,6 @@ struct LLSECKeywordCompare
 
 LLScriptEdCore::LLScriptEdCore(
 	const std::string& sample,
-	const std::string& help_url,
 	const LLHandle<LLFloater>& floater_handle,
 	void (*load_callback)(void*),
 	void (*save_callback)(void*, BOOL),
@@ -274,7 +274,6 @@ LLScriptEdCore::LLScriptEdCore(
 	:
 	LLPanel(),
 	mSampleText(sample),
-	mHelpURL(help_url),
 	mEditor( NULL ),
 	mLoadCallback( load_callback ),
 	mSaveCallback( save_callback ),
@@ -436,7 +435,7 @@ void LLScriptEdCore::initMenu()
 	menuItem = getChild<LLMenuItemCallGL>("Help...");
 	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
 
-	menuItem = getChild<LLMenuItemCallGL>("LSL Wiki Help...");
+	menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
 	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
 }
 
@@ -539,9 +538,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
 			mLiveHelpTimer.stop();
 		}
 	}
-	else if (immediate)
+	else
 	{
-		setHelpPage(LLStringUtil::null);
+		if (immediate)
+		{
+			setHelpPage(LLStringUtil::null);
+		}
 	}
 }
 
@@ -557,6 +559,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string)
 	if (!history_combo) return;
 
 	LLUIString url_string = gSavedSettings.getString("LSLHelpURL");
+
 	url_string.setArg("[LSL_STRING]", help_string);
 
 	addHelpItemToHistory(help_string);
@@ -647,69 +650,52 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
 	return false;
 }
 
-// static 
-bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotification::getSelectedOption(notification, response);
-
-	switch(option)
-	{
-	case 0:
-		LLWeb::loadURL(notification["payload"]["help_url"]);
-		break;
-	default:
-		break;
-	}
-	return false;
-}
-
 void LLScriptEdCore::onBtnHelp()
 {
-	LLSD payload;
-	payload["help_url"] = mHelpURL;
-	LLNotifications::instance().add("WebLaunchLSLGuide", LLSD(), payload, onHelpWebDialog);
+	LLUI::sHelpImpl->showTopic(HELP_LSL_PORTAL_TOPIC);
 }
 
 void LLScriptEdCore::onBtnDynamicHelp()
 {
 	LLFloater* live_help_floater = mLiveHelpHandle.get();
-	if (live_help_floater)
-	{
-		live_help_floater->setFocus(TRUE);
-		updateDynamicHelp(TRUE);
+	if (!live_help_floater)
+	{
+		live_help_floater = new LLFloater(LLSD());
+		LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL);
+		LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
+		parent->addDependentFloater(live_help_floater, TRUE);
+		live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this);
+		live_help_floater->childSetValue("lock_check", gSavedSettings.getBOOL("ScriptHelpFollowsCursor"));
+		live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, this);
+		live_help_floater->childSetAction("back_btn", onClickBack, this);
+		live_help_floater->childSetAction("fwd_btn", onClickForward, this);
+
+		LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
+		browser->setAlwaysRefresh(TRUE);
+
+		LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo");
+		LLKeywordToken *token;
+		LLKeywords::keyword_iterator_t token_it;
+		for (token_it = mEditor->keywordsBegin(); 
+		     token_it != mEditor->keywordsEnd(); 
+		     ++token_it)
+		{
+			token = token_it->second;
+			help_combo->add(wstring_to_utf8str(token->getToken()));
+		}
+		help_combo->sortByName();
 
-		return;
+		// re-initialize help variables
+		mLastHelpToken = NULL;
+		mLiveHelpHandle = live_help_floater->getHandle();
+		mLiveHelpHistorySize = 0;
 	}
 
-	live_help_floater = new LLFloater(LLSD());
-	LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL);
-	LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
-	parent->addDependentFloater(live_help_floater, TRUE);
-	live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this);
-	live_help_floater->childSetValue("lock_check", gSavedSettings.getBOOL("ScriptHelpFollowsCursor"));
-	live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, this);
-	live_help_floater->childSetAction("back_btn", onClickBack, this);
-	live_help_floater->childSetAction("fwd_btn", onClickForward, this);
-
-	LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
-	browser->setAlwaysRefresh(TRUE);
-
-	LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo");
-	LLKeywordToken *token;
-	LLKeywords::keyword_iterator_t token_it;
-	for (token_it = mEditor->keywordsBegin(); 
-		token_it != mEditor->keywordsEnd(); 
-		++token_it)
-	{
-		token = token_it->second;
-		help_combo->add(wstring_to_utf8str(token->getToken()));
-	}
-	help_combo->sortByName();
+	BOOL visible = TRUE;
+	BOOL take_focus = TRUE;
+	live_help_floater->setVisible(visible);
+	live_help_floater->setFrontmost(take_focus);
 
-	// re-initialize help variables
-	mLastHelpToken = NULL;
-	mLiveHelpHandle = live_help_floater->getHandle();
-	mLiveHelpHistorySize = 0;
 	updateDynamicHelp(TRUE);
 }
 
@@ -945,7 +931,6 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
 
 	self->mScriptEd =  new LLScriptEdCore(
 								   HELLO_LSL,
-								   HELP_LSL_URL,
 								   self->getHandle(),
 								   LLPreviewLSL::onLoad,
 								   LLPreviewLSL::onSave,
@@ -1411,7 +1396,6 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
 
 	self->mScriptEd =  new LLScriptEdCore(
 								   HELLO_LSL,
-								   HELP_LSL_URL,
 								   self->getHandle(),
 								   &LLLiveLSLEditor::onLoad,
 								   &LLLiveLSLEditor::onSave,
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 623886101ae8289b2a76b5e87e482743ab0cdcc8..a00f580e327cd548572d4156417e270d283f58e9 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -64,7 +64,6 @@ class LLScriptEdCore : public LLPanel
 public:
 	LLScriptEdCore(
 		const std::string& sample,
-		const std::string& help_url,
 		const LLHandle<LLFloater>& floater_handle,
 		void (*load_callback)(void* userdata),
 		void (*save_callback)(void* userdata, BOOL close_after_save),
@@ -86,7 +85,6 @@ class LLScriptEdCore : public LLPanel
 	bool			handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
 	bool			handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
 
-	static bool		onHelpWebDialog(const LLSD& notification, const LLSD& response);
 	static void		onCheckLock(LLUICtrl*, void*);
 	static void		onHelpComboCommit(LLUICtrl* ctrl, void* userdata);
 	static void		onClickBack(void* userdata);
@@ -116,7 +114,6 @@ class LLScriptEdCore : public LLPanel
 
 private:
 	std::string		mSampleText;
-	std::string		mHelpURL;
 	LLTextEditor*	mEditor;
 	void			(*mLoadCallback)(void* userdata);
 	void			(*mSaveCallback)(void* userdata, BOOL close_after_save);
@@ -124,7 +121,6 @@ class LLScriptEdCore : public LLPanel
 	void*			mUserdata;
 	LLComboBox		*mFunctions;
 	BOOL			mForceClose;
-	//LLPanel*		mGuiPanel;
 	LLPanel*		mCodePanel;
 	LLScrollListCtrl* mErrorList;
 	LLDynamicArray<LLEntryAndEdCore*> mBridges;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 082bba027ffe1c40a353a1814027c771eb52a35f..8a96a5a1ae17198a601f920c96a12316d70ede16 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -55,36 +55,30 @@ using namespace LLNotificationsUI;
 bool LLScreenChannel::mWasStartUpToastShown = false;
 
 //--------------------------------------------------------------------------
-LLScreenChannel::LLScreenChannel(LLUUID& id):	mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
-												mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
-												mHiddenToastsNum(0), mOverflowToastHidden(false),
-												mIsHovering(false), mControlHovering(false),
-												mShowToasts(true)
+//////////////////////
+// LLScreenChannelBase
+//////////////////////
+LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
+												mOverflowToastPanel(NULL) 
+												,mToastAlignment(NA_BOTTOM)
+												,mCanStoreToasts(true)
+												,mHiddenToastsNum(0)
+												,mOverflowToastHidden(false)
+												,mIsHovering(false)
+												,mControlHovering(false)
+												,mShowToasts(true)
 {	
 	mID = id;
 	mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
-	mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannel::updatePositionAndSize, this, _1, _2));
+	mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
 	setMouseOpaque( false );
 	setVisible(FALSE);
 }
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::init(S32 channel_left, S32 channel_right)
-{
-	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
-	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
-	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
-	setVisible(TRUE);
-}
-
-//--------------------------------------------------------------------------
-LLScreenChannel::~LLScreenChannel() 
+LLScreenChannelBase::~LLScreenChannelBase()
 {
 	mWorldViewRectConnection.disconnect();
 }
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
 {
 	S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
 	S32 right_delta = old_world_rect.mRight - new_world_rect.mRight;
@@ -105,6 +99,42 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
 	}
 	setRect(this_rect);
 	redrawToasts();
+	
+}
+
+void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
+{
+	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+	setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+//////////////////////
+// LLScreenChannel
+//////////////////////
+//--------------------------------------------------------------------------
+LLScreenChannel::LLScreenChannel(LLUUID& id):	LLScreenChannelBase(id)
+{	
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+	LLScreenChannelBase::init(channel_left, channel_right);
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel::~LLScreenChannel() 
+{
+	
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+{
+	LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
 }
 
 //--------------------------------------------------------------------------
@@ -112,7 +142,7 @@ void LLScreenChannel::addToast(LLToast::Params p)
 {
 	bool store_toast = false, show_toast = false;
 
-	show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+	mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
 	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
 
 	if(!show_toast && !store_toast)
@@ -561,7 +591,7 @@ void LLScreenChannel::removeAndStoreAllStorableToasts()
 		else
 		{
 			++it;
-	}
+		}
 	}
 	redrawToasts();
 }
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f1ef6bd64df22986fcb10e3a9ea7f99ea0de40d2..459c28ac7c3a6ac06e7011663b8f292097fa66d6 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -55,10 +55,95 @@ typedef enum e_channel_alignment
 	CA_RIGHT,
 } EChannelAlignment;
 
+class LLScreenChannelBase : public LLUICtrl
+{
+	friend class LLChannelManager;
+public:
+	LLScreenChannelBase(const LLUUID& id);
+	~LLScreenChannelBase();
+
+	// Channel's outfit-functions
+	// update channel's size and position in the World View
+	virtual void		updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
+	// initialization of channel's shape and position
+	virtual void		init(S32 channel_left, S32 channel_right);
+
+
+	virtual void		setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
+	
+	virtual void		setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
+	virtual void		setOverflowFormatString ( const std::string& str)  { mOverflowFormatString = str; }
+	
+	// kill or modify a toast by its ID
+	virtual void		killToastByNotificationID(LLUUID id) {};
+	virtual void		modifyToastNotificationByID(LLUUID id, LLSD data) {};
+	
+	// hide all toasts from screen, but not remove them from a channel
+	virtual void		hideToastsFromScreen() {};
+	// removes all toasts from a channel
+	virtual void		removeToastsFromChannel() {};
+	
+	// show all toasts in a channel
+	virtual void		redrawToasts() {};
+
+	virtual void 		closeOverflowToastPanel() {};
+	virtual void 		hideOverflowToastPanel() {};
+
+	
+	// Channel's behavior-functions
+	// set whether a channel will control hovering inside itself or not
+	virtual void setControlHovering(bool control) { mControlHovering = control; }
+	// set Hovering flag for a channel
+	virtual void setHovering(bool hovering) { mIsHovering = hovering; }
+	
+	void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
+
+	void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
+	bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
+
+	// get number of hidden notifications from a channel
+	S32	 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+
+	
+	void setShowToasts(bool show) { mShowToasts = show; }
+	bool getShowToasts() { return mShowToasts; }
+
+	// get toast allignment preset for a channel
+	e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+	
+	// get ID of a channel
+	LLUUID	getChannelID() { return mID; }
+
+protected:
+	// Channel's flags
+	bool		mControlHovering;
+	bool		mIsHovering;
+	bool		mCanStoreToasts;
+	bool		mDisplayToastsAlways;
+	bool		mOverflowToastHidden;
+	// controls whether a channel shows toasts or not
+	bool		mShowToasts;
+	// 
+	EToastAlignment		mToastAlignment;
+	EChannelAlignment	mChannelAlignment;
+
+	// attributes for the Overflow Toast
+	S32			mHiddenToastsNum;
+	LLToast*	mOverflowToastPanel;	
+	std::string mOverflowFormatString;
+
+	// channel's ID
+	LLUUID	mID;
+
+	// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
+	boost::signals2::connection mWorldViewRectConnection;
+};
+
+
 /**
  * Screen channel manages toasts visibility and positioning on the screen.
  */
-class LLScreenChannel : public LLUICtrl
+class LLScreenChannel : public LLScreenChannelBase
 {
 	friend class LLChannelManager;
 public:
@@ -70,12 +155,6 @@ class LLScreenChannel : public LLUICtrl
 	void		updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
 	// initialization of channel's shape and position
 	void		init(S32 channel_left, S32 channel_right);
-	// set allignment of toasts inside a channel
-	void		setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
-	// set allignment of channel inside a world view
-	void		setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
-	// set a template for a string in the OverflowToast
-	void		setOverflowFormatString ( std::string str)  { mOverflowFormatString = str; }
 	
 	// Operating with toasts
 	// add a toast to a channel
@@ -104,37 +183,17 @@ class LLScreenChannel : public LLUICtrl
 	// close the StartUp Toast
 	void		closeStartUpToast();
 
-	// Channel's behavior-functions
-	// set whether a channel will control hovering inside itself or not
-	void setControlHovering(bool control) { mControlHovering = control; }
-	// set Hovering flag for a channel
-	void setHovering(bool hovering) { mIsHovering = hovering; }
-	// set whether a channel will store faded toasts or not
-	void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
-	// tell all channels that the StartUp toast was shown and allow them showing of toasts
-	static void	setStartUpToastShown() { mWasStartUpToastShown = true; }
 	// get StartUp Toast's state
 	static bool	getStartUpToastShown() { return mWasStartUpToastShown; }
-	// set mode for dislaying of toasts
-	void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
-	// get mode for dislaying of toasts
-	bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
-	// tell a channel to show toasts or not
-	void setShowToasts(bool show) { mShowToasts = show; }
-	// determine whether channel shows toasts or not
-	bool getShowToasts() { return mShowToasts; }
+	// tell all channels that the StartUp toast was shown and allow them showing of toasts
+	static void	setStartUpToastShown() { mWasStartUpToastShown = true; }
 	// let a channel update its ShowToast flag
 	void updateShowToastsState();
 
+
 	// Channel's other interface functions functions
-	// get number of hidden notifications from a channel
-	S32		getNumberOfHiddenToasts() { return mHiddenToastsNum;}
 	// update number of notifications in the StartUp Toast
 	void	updateStartUpString(S32 num);
-	// get toast allignment preset for a channel
-	e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
-	// get ID of a channel
-	LLUUID	getChannelID() { return mID; }
 
 	// Channel's signals
 	// signal on storing of faded toasts event
@@ -201,30 +260,10 @@ class LLScreenChannel : public LLUICtrl
 
 	// Channel's flags
 	static bool	mWasStartUpToastShown;
-	bool		mControlHovering;
-	bool		mIsHovering;
-	bool		mCanStoreToasts;
-	bool		mDisplayToastsAlways;
-	bool		mOverflowToastHidden;
-	// controls whether a channel shows toasts or not
-	bool		mShowToasts;
-	// 
-	EToastAlignment		mToastAlignment;
-	EChannelAlignment	mChannelAlignment;
-
-	// attributes for the Overflow Toast
-	S32			mHiddenToastsNum;
-	LLToast*	mOverflowToastPanel;	
-	std::string mOverflowFormatString;
 
 	// attributes for the StartUp Toast	
 	LLToast* mStartUpToastPanel;
 
-	// channel's ID
-	LLUUID	mID;
-
-	// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
-	boost::signals2::connection mWorldViewRectConnection;
 
 	std::vector<ToastElem>		mToastList;
 	std::vector<ToastElem>		mStoredToastList;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index b25331e43935097a510a82ee3d4ff6b3f4e0d279..ae8c9f770b9c71e996d6986c3a70b7c878cb4d86 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1721,13 +1721,8 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright)
 	getSelection()->applyToObjects(&sendfunc);
 }
 
-void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
+void LLSelectMgr::selectionSetMedia(U8 media_type)
 {
-	U8 media_flags = LLTextureEntry::MF_NONE;
-	if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
-	{
-		media_flags = LLTextureEntry::MF_WEB_PAGE;
-	}
 	
 	struct f : public LLSelectedTEFunctor
 	{
@@ -1737,33 +1732,72 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string&
 		{
 			if (object->permModify())
 			{
-				// update viewer side color in anticipation of update from simulator
+				// update viewer has media
 				object->setTEMediaFlags(te, mMediaFlags);
 			}
 			return true;
 		}
-	} setfunc(media_flags);
+	} setfunc(media_type);
 	getSelection()->applyToTEs(&setfunc);
-
-	struct g : public LLSelectedObjectFunctor
+	struct f2 : public LLSelectedObjectFunctor
 	{
-		U8 media_type;
-		const std::string& media_url ;
-		g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
 		virtual bool apply(LLViewerObject* object)
 		{
 			if (object->permModify())
 			{
 				object->sendTEUpdate();
-				object->setMediaType(media_type);
-				object->setMediaURL(media_url);
 			}
 			return true;
 		}
-	} sendfunc(media_type, media_url);
-	getSelection()->applyToObjects(&sendfunc);
+	} func2;
+	mSelectedObjects->applyToObjects( &func2 );
 }
 
+// This function expects media_data to be a map containing relevant
+// media data name/value pairs (e.g. home_url, etc.)
+void LLSelectMgr::selectionSetMediaData(const LLSD &media_data)
+{
+
+	struct f : public LLSelectedTEFunctor
+	{
+		const LLSD &mMediaData;
+		f(const LLSD& t) : mMediaData(t) {}
+		bool apply(LLViewerObject* object, S32 te)
+		{
+			if (object->permModify())
+			{
+                LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+                if (NULL != vo) 
+                {
+                    vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
+                }                
+			}
+			return true;
+		}
+	} setfunc(media_data);
+	getSelection()->applyToTEs(&setfunc);
+
+	struct f2 : public LLSelectedObjectFunctor
+	{
+		virtual bool apply(LLViewerObject* object)
+		{
+			if (object->permModify())
+			{
+                LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+                if (NULL != vo) 
+                {
+                    // Send updated media data FOR THE ENTIRE OBJECT
+                    vo->sendMediaDataUpdate();
+                }
+			}
+			return true;
+		}
+	} func2;
+	getSelection()->applyToObjects(&func2);
+}
+
+
+
 void LLSelectMgr::selectionSetGlow(F32 glow)
 {
 	struct f1 : public LLSelectedTEFunctor
@@ -5057,7 +5091,15 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected)
 	{
 		return;
 	}
-	mTESelectMask |= 0x1 << te_index;
+	S32 mask = 0x1 << te_index;
+	if(selected)
+	{	
+		mTESelectMask |= mask;
+	}
+	else
+	{
+		mTESelectMask &= ~mask;
+	}
 	mLastTESelected = te_index;
 }
 
@@ -6042,6 +6084,29 @@ bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool first
 	return result;
 }
 
+BOOL LLObjectSelection::isMultipleTESelected()
+{
+	BOOL te_selected = FALSE;
+	// ...all faces
+	for (LLObjectSelection::iterator iter = begin();
+		 iter != end(); iter++)
+	{
+		LLSelectNode* nodep = *iter;
+		for (S32 i = 0; i < SELECT_MAX_TES; i++)
+		{
+			if(nodep->isTESelected(i))
+			{
+				if(te_selected)
+				{
+					return TRUE;
+				}
+				te_selected = TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
 //-----------------------------------------------------------------------------
 // contains()
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 08c27837462f778893229e0a536db93ebbc6528c..9e02170d74a360d1cebc5694f0cefb9e4ff1f1ef 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -307,6 +307,7 @@ class LLObjectSelection : public LLRefCount
 	S32 getTECount();
 	S32 getRootObjectCount();
 
+	BOOL isMultipleTESelected();
 	BOOL contains(LLViewerObject* object);
 	BOOL contains(LLViewerObject* object, S32 te);
 
@@ -504,7 +505,8 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	void selectionSetTexGen( U8 texgen );
 	void selectionSetShiny( U8 shiny );
 	void selectionSetFullbright( U8 fullbright );
-	void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url );
+	void selectionSetMedia( U8 media_type );
+	void selectionSetMediaData(const LLSD &media_data); // NOTE: modifies media_data!!!
 	void selectionSetClickAction(U8 action);
 	void selectionSetIncludeInSearch(bool include_in_search);
 	void selectionSetGlow(const F32 glow);
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 381e63f020baf6f45c214d737f8da3044dafdc9d..2be0aa40d2893a6c67712c7e887232f3fe7c9be6 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -48,6 +48,7 @@
 #include "lliconctrl.h"//for Home tab icon
 #include "llsidetraypanelcontainer.h"
 #include "llwindow.h"//for SetCursor
+#include "lltransientfloatermgr.h"
 
 //#include "llscrollcontainer.h"
 
@@ -248,6 +249,7 @@ LLSideTray::LLSideTray(Params& params)
 	// register handler function to process data from the xml. 
 	// panel_name should be specified via "parameter" attribute.
 	commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
+	LLTransientFloaterMgr::getInstance()->addControlView(this);
 }
 
 
@@ -448,13 +450,17 @@ void LLSideTray::reflectCollapseChange()
 	setPanelRect();
 
 	if(mCollapsed)
+	{
 		gFloaterView->setSnapOffsetRight(0);
+		setFocus(FALSE);
+	}
 	else
+	{
 		gFloaterView->setSnapOffsetRight(mMaxBarWidth);
+		setFocus(TRUE);
+	}
 
 	gFloaterView->refresh();
-
-	setFocus( FALSE );
 }
 
 void LLSideTray::arrange			()
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 4e13cb17a2ab1081c57f9cfc45a8d38feefacb29..7bf0d31d94f68a246ddb48ae800e3a1625376c6e 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -433,6 +433,11 @@ void LLSpatialGroup::clearDrawMap()
 	mDrawMap.clear();
 }
 
+BOOL LLSpatialGroup::isRecentlyVisible() const
+{
+	return (LLDrawable::getCurrentFrame() - (S32)mVisible) < LLDrawable::getMinVisFrameRange() ;
+}
+
 BOOL LLSpatialGroup::isVisible() const
 {
 	return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 16e8782a8e06d2093c3bcf24586dd1ebf46c1ca0..64c2a9acbc7d94d7da76ad693d94b5e7217a1803 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -267,6 +267,7 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
 	BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
 	BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
 	BOOL isVisible() const;
+	BOOL isRecentlyVisible() const;
 	void setVisible();
 	void shift(const LLVector3 &offset);
 	BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6a55b571aec81b67f9d70987bde0a481b256d52a..053b863b6dbc531165e55fb44d43913fd71eeef8 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1429,6 +1429,17 @@ bool idle_startup()
 				LLStartUp::deletePasswordFromDisk();
 			}
 
+			// this is the base used to construct help URLs
+			text = LLUserAuth::getInstance()->getResponse("help_url_format");
+			if (!text.empty())
+			{
+				// replace the default help URL format
+				gSavedSettings.setString("HelpURLFormat",text);
+				
+				// don't fall back to Nebraska's pre-connection static help
+				gSavedSettings.setBOOL("HelpUseLocal", false);
+			}
+			
 			// this is their actual ability to access content
 			text = LLUserAuth::getInstance()->getResponse("agent_access_max");
 			if (!text.empty())
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index d7df258750ad3ca854166abb1f8c7b5a724804b0..b0930cd86de1c84fa170ab69b020c0482c21ba48 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -225,22 +225,14 @@ void LLStatusBar::draw()
 
 BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (mHideNavbarContextMenu)
-	{
-		mHideNavbarContextMenu->buildDrawLabels();
-		mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
-		LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
-	}
-
+	show_navbar_context_menu(this,x,y);
 	return TRUE;
 }
 
 BOOL LLStatusBar::postBuild()
 {
-	mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	gMenuHolder->addChild(mHideNavbarContextMenu);
 
-	gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
+	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
 
 	return TRUE;
 }
@@ -560,11 +552,6 @@ void LLStatusBar::setupDate()
 	}
 }
 
-void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
-{
-	handleRightMouseDown(x, y, mask);
-}
-
 // static
 void LLStatusBar::onClickStatGraph(void* data)
 {
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 81a69e9590e109ceab8c379bc222d3fbe7ba99bf..d5629e6f1ebd7bb35ea4899636fd4ab4a4bef1b4 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -91,7 +91,6 @@ class LLStatusBar
 	// simple method to setup the part that holds the date
 	void setupDate();
 
-	void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
 	static void onCommitSearch(LLUICtrl*, void* data);
 	static void onClickSearch(void* data);
 	static void onClickStatGraph(void* data);
@@ -111,8 +110,7 @@ class LLStatusBar
 	S32				mSquareMetersCommitted;
 	LLFrameTimer*	mBalanceTimer;
 	LLFrameTimer*	mHealthTimer;
-	LLMenuGL*		mHideNavbarContextMenu;
-	
+		
 	static std::vector<std::string> sDays;
 	static std::vector<std::string> sMonths;
 	static const U32 MAX_DATE_STRING_LENGTH;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index c1eecf4c12cf6239582ff81cb4b00056748c2985..669d8d1d70f62a7df7264c9b29621e3ea13f0451 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -108,6 +108,15 @@ BOOL LLSysWellWindow::postBuild()
 	return LLDockableFloater::postBuild();
 }
 
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::setMinimized(BOOL minimize)
+{
+	// we don't show empty Message Well window
+	setVisible(!minimize && !isWindowEmpty());
+
+	LLFloater::setMinimized(minimize);
+}
+
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
 {
@@ -155,10 +164,10 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
 	{
 		handleItemAdded(IT_NOTIFICATION);
 
-	reshapeWindow();
+		reshapeWindow();
 
-	new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
-	new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+		new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+		new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
 	}
 	else
 	{
@@ -226,11 +235,11 @@ void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::initChannel() 
 {
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+	LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
 																LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
-	if(channel)
+	mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+	if(mChannel)
 	{
-		mChannel = channel;
 		mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
 	}
 	else
@@ -240,7 +249,7 @@ void LLSysWellWindow::initChannel()
 }
 
 //---------------------------------------------------------------------------------
-void LLSysWellWindow::getEnabledRect(LLRect& rect)
+void LLSysWellWindow::getAllowedRect(LLRect& rect)
 {
 	rect = gViewerWindow->getWorldViewRect();
 }
@@ -252,7 +261,7 @@ void LLSysWellWindow::toggleWindow()
 	{
 		setDockControl(new LLDockControl(
 				LLBottomTray::getInstance()->getSysWell(), this,
-				getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getEnabledRect, this, _1)));
+				getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
 	}
 
 	if(!getVisible())
@@ -404,20 +413,18 @@ bool LLSysWellWindow::isWindowEmpty()
 
 //---------------------------------------------------------------------------------
 //virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
-		const std::string& name, const LLUUID& otherParticipantId)
+void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
+		const std::string& name, const LLUUID& other_participant_id)
 {
-	if (mMessageList->getItemByValue(get_session_value(sessionId)) == NULL)
+	//*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
+	if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL)
 	{
-		S32 chicletCounter = 0;
-		LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
-				sessionId, (LLIMModel::LLIMSession*) NULL);
-		if (session != NULL)
+		S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
+		if (chicletCounter > -1)
 		{
-			chicletCounter = session->mNumUnread;
+			addIMRow(session_id, chicletCounter, name, other_participant_id);	
+			reshapeWindow();
 		}
-		addIMRow(sessionId, chicletCounter, name, otherParticipantId);
-		reshapeWindow();
 	}
 }
 
@@ -491,6 +498,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
 	switch (im_chiclet_type)
 	{
 	case LLIMChiclet::TYPE_GROUP:
+	case LLIMChiclet::TYPE_AD_HOC:
 		mChiclet = getChild<LLIMChiclet>("group_chiclet");
 		childSetVisible("p2p_chiclet", false);
 		break;
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 37a2690a828f651023460f69d9e3c375df196eb2..203b94971547abb55250136b4ed11594c9809ab0 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -68,6 +68,8 @@ class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
 	void toggleWindow();
 	/*virtual*/ BOOL	canClose() { return FALSE; }
 	/*virtual*/ void	setDocked(bool docked, bool pop_on_undock = true);
+	// override LLFloater's minimization according to EXT-1216
+	/*virtual*/ void	setMinimized(BOOL minimize);
 
 	// Handlers
 	void onItemClick(LLSysWellItem* item);
@@ -86,8 +88,8 @@ class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
 		IT_INSTANT_MESSAGE
 	}EItemType; 
 
-	// gets a rect valid for SysWellWindow's position on a screen (EXT-1111)
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 	// connect counter and list updaters to the corresponding signals
 	void connectListUpdaterToSignal(std::string notification_type);
 	// init Window's channel
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 97a15759bf8ccb78ad019e1d4d5b7591bd41d0fb..84931e4d2dcedc42c8cd557854efa0f47d77be5f 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -41,7 +41,7 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLToast::LLToast(LLToast::Params p) :	LLFloater(LLSD()), 
+LLToast::LLToast(LLToast::Params p) :	LLModalDialog(LLSD(), p.is_modal),
 										mPanel(p.panel), 
 										mTimerValue(p.timer_period),  
 										mNotificationID(p.notif_id),  
@@ -49,7 +49,6 @@ LLToast::LLToast(LLToast::Params p) :	LLFloater(LLSD()),
 										mCanFade(p.can_fade),
 										mCanBeStored(p.can_be_stored),
 										mHideBtnEnabled(p.enable_hide_btn),
-										mIsModal(p.is_modal),
 										mHideBtn(NULL),
 										mNotification(p.notification),
 										mHideBtnPressed(false)
@@ -67,13 +66,6 @@ LLToast::LLToast(LLToast::Params p) :	LLFloater(LLSD()),
 		mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
 	}
 
-	if(mIsModal)
-	{
-		gFocusMgr.setMouseCapture( this );
-		gFocusMgr.setTopCtrl( this );
-		setFocus(TRUE);
-	}
-
 	// init callbacks if present
 	if(!p.on_delete_toast.empty())
 		mOnDeleteToastSignal.connect(p.on_delete_toast);
@@ -104,11 +96,6 @@ void LLToast::setHideButtonEnabled(bool enabled)
 LLToast::~LLToast()
 {	
 	mOnToastDestroyedSignal(this);
-	if(mIsModal)
-	{
-		gFocusMgr.unlockFocus();
-		gFocusMgr.releaseFocusIfNeeded( this );
-	}
 }
 
 //--------------------------------------------------------------------------
@@ -167,15 +154,30 @@ void LLToast::tick()
 }
 
 //--------------------------------------------------------------------------
-void LLToast::insertPanel(LLPanel* panel)
+
+void LLToast::reshapeToPanel()
 {
-	LLRect panel_rect, toast_rect;
+	LLPanel* panel = getPanel();
+	if(!panel)
+		return;
+
+	LLRect panel_rect;
 
 	panel_rect = panel->getRect();
 	reshape(panel_rect.getWidth(), panel_rect.getHeight());
 	panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
 	panel->setRect(panel_rect);
+	
+	LLRect toast_rect = getRect();
+	toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
+	setRect(toast_rect);
+
+}
+
+void LLToast::insertPanel(LLPanel* panel)
+{
 	addChild(panel);	
+	reshapeToPanel();
 }
 
 //--------------------------------------------------------------------------
@@ -189,18 +191,6 @@ void LLToast::draw()
 	LLFloater::draw();
 }
 
-//--------------------------------------------------------------------------
-void LLToast::setModal(bool modal)
-{
-	mIsModal = modal;
-	if(mIsModal)
-	{
-		gFocusMgr.setMouseCapture( this );
-		gFocusMgr.setTopCtrl( this );
-		setFocus(TRUE);
-	}
-}
-
 //--------------------------------------------------------------------------
 void LLToast::setVisible(BOOL show)
 {
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 9248747c439ebb38d0f8ba7da177f76140c0084d..29c231a01d9a41911244cc25964507f2ccd18fa3 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -35,7 +35,7 @@
 
 
 #include "llpanel.h"
-#include "llfloater.h"
+#include "llmodaldialog.h"
 #include "lltimer.h"
 #include "llnotifications.h"
 
@@ -51,7 +51,7 @@ namespace LLNotificationsUI
  * Represents toast pop-up.
  * This is a parent view for all toast panels.
  */
-class LLToast : public LLFloater
+class LLToast : public LLModalDialog
 {
 public:
 	typedef boost::function<void (LLToast* toast)> toast_callback_t;
@@ -99,6 +99,9 @@ class LLToast : public LLFloater
 	// Operating with toasts
 	// insert a panel to a toast
 	void insertPanel(LLPanel* panel);
+
+	void reshapeToPanel();
+
 	// get toast's panel
 	LLPanel* getPanel() { return mPanel; }
 	// enable/disable Toast's Hide button
@@ -131,8 +134,6 @@ class LLToast : public LLFloater
 	void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; }
 	//
 	bool getCanBeStored() { return mCanBeStored; }
-	//
-	void setModal(bool modal);
 
 
 	// Registers signals/callbacks for events
@@ -168,7 +169,6 @@ class LLToast : public LLFloater
 
 	LLColor4	mBgColor;
 	bool		mCanFade;
-	bool		mIsModal;
 	bool		mCanBeStored;
 	bool		mHideBtnEnabled;
 	bool		mHideBtnPressed;
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index bc9888f4b48527d391c2917bbfa9a0d4961975e8..418373e8c6067614ffa262f2ad608ae98e3572ea 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -39,6 +39,12 @@
 
 #include <string>
 
+class LLToastPanelBase: public LLPanel 
+{
+public:
+	virtual void init(LLSD& data){};
+};
+
 /**
  * Base class for all panels that can be added to the toast.
  * All toast panels should contain necessary logic for representing certain notification
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index ceb1358d1c0772ae86c6fc3abfb6adb32dab33f0..880d5d5e1226df51d91b85d506d2822bdb07c79d 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -67,18 +67,20 @@ LLTool::~LLTool()
 
 BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
 {
-	// This is necessary to force clicks in the world to cause edit
-	// boxes that might have keyboard focus to relinquish it, and hence
-	// cause a commit to update their value.  JC
-	if (down)
+	BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+	
+	// This behavior was moved here from LLViewerWindow::handleAnyMouseClick, so it can be selectively overridden by LLTool subclasses.
+	if(down && result)
 	{
+		// This is necessary to force clicks in the world to cause edit
+		// boxes that might have keyboard focus to relinquish it, and hence
+		// cause a commit to update their value.  JC
 		gFocusMgr.setKeyboardFocus(NULL);
 	}
-
-	return LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+	
+	return result;
 }
 
-
 BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	if (gDebugClicks)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 5c210c5c28a1088c28fafac770e15a1d50bf1984..d5db22414320d3e3696a77095486e0810e4fffd7 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -48,6 +48,7 @@
 #include "lltooltip.h"
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
+#include "llmediaentry.h"
 #include "llmenugl.h"
 #include "llmutelist.h"
 #include "llselectmgr.h"
@@ -75,8 +76,6 @@ extern void handle_buy(void*);
 
 extern BOOL gDebugClicks;
 
-static bool handle_media_click(const LLPickInfo& info);
-static bool handle_media_hover(const LLPickInfo& info);
 static void handle_click_action_play();
 static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
 static ECursorType cursor_from_parcel_media(U8 click_action);
@@ -90,6 +89,16 @@ LLToolPie::LLToolPie()
 { }
 
 
+BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+{
+	BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+	
+	// This override DISABLES the keyboard focus reset that LLTool::handleAnyMouseClick adds.
+	// LLToolPie will do the right thing in its pick callback.
+	
+	return result;
+}
+
 BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	//left mouse down always picks transparent
@@ -258,9 +267,9 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 		}
 	}
 
-	if (handle_media_click(mPick))
+	if (handleMediaClick(mPick))
 	{
-		return FALSE;
+		return TRUE;
 	}
 
 	// put focus back "in world"
@@ -466,10 +475,7 @@ void LLToolPie::selectionPropertiesReceived()
 BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 {
 	mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE);
-
-	// FIXME: This was in the pluginapi branch, but I don't think it's correct.
-//	gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
-
+	
 	LLViewerObject *parent = NULL;
 	LLViewerObject *object = mHoverPick.getObject();
 
@@ -484,7 +490,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 		gViewerWindow->setCursor(cursor);
 		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
 	}
-	else if (handle_media_hover(mHoverPick))
+	else if (handleMediaHover(mHoverPick))
 	{
 		// cursor set by media object
 		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
@@ -522,6 +528,9 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 {
 	LLViewerObject* obj = mPick.getObject();
+
+	handleMediaMouseUp();
+
 	U8 click_action = final_click_action(obj);
 	if (click_action != CLICK_ACTION_NONE)
 	{
@@ -543,6 +552,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 			break;
 		}
 	}
+
 	mGrabMouseButtonDown = FALSE;
 	LLToolMgr::getInstance()->clearTransientTool();
 	gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
@@ -1038,6 +1048,7 @@ void LLToolPie::stopEditing()
 void LLToolPie::onMouseCaptureLost()
 {
 	mMouseOutsideSlop = FALSE;
+	handleMediaMouseUp();
 }
 
 
@@ -1078,7 +1089,7 @@ static void handle_click_action_play()
 	}
 }
 
-static bool handle_media_click(const LLPickInfo& pick)
+bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
 {
 	//FIXME: how do we handle object in different parcel than us?
 	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@@ -1104,22 +1115,25 @@ static bool handle_media_click(const LLPickInfo& pick)
 
 	// is media playing on this face?
 	const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+	LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
+	viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
 
-	viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
-	if (tep
-		&& media_impl.notNull()
-		&& media_impl->hasMedia()
-		&& gSavedSettings.getBOOL("MediaOnAPrimUI"))
+	if (tep 
+		&& mep
+		&& gSavedSettings.getBOOL("MediaOnAPrimUI")
+		&& media_impl.notNull())
 	{
-		LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection(); 
-		if (! selection->contains(pick.getObject(), pick.mObjectFace))
+		// LLObjectSelectionHandle selection = /*LLViewerMediaFocus::getInstance()->getSelection()*/ LLSelectMgr::getInstance()->getSelection();
+		if (/*! selection->contains(pick.getObject(), pick.mObjectFace)*/
+			! LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) )
 		{
 			LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl);
 		}
 		else
 		{
-			media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY);
-			media_impl->mouseCapture(); // the mouse-up will happen when capture is lost
+			media_impl->mouseDown(pick.mUVCoords);
+			mMediaMouseCaptureID = mep->getMediaID();
+			setMouseCapture(TRUE);  // This object will send a mouse-up to the media when it loses capture.
 		}
 
 		return true;
@@ -1131,7 +1145,7 @@ static bool handle_media_click(const LLPickInfo& pick)
 	return false;
 }
 
-static bool handle_media_hover(const LLPickInfo& pick)
+bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
 {
 	//FIXME: how do we handle object in different parcel than us?
 	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@@ -1156,15 +1170,20 @@ static bool handle_media_hover(const LLPickInfo& pick)
 
 	// is media playing on this face?
 	const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
-	viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
-	if (tep
-		&& media_impl.notNull()
-		&& media_impl->hasMedia()
+	const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+	if (mep
 		&& gSavedSettings.getBOOL("MediaOnAPrimUI"))
-	{
-		if(LLViewerMediaFocus::getInstance()->getFocus())
+	{		
+		viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+		if(LLViewerMediaFocus::getInstance()->getFocus() && media_impl.notNull())
 		{
-			media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY);
+			media_impl->mouseMove(pick.mUVCoords);
+
+			gViewerWindow->setCursor(media_impl->getLastSetCursor());
+		}
+		else
+		{
+			gViewerWindow->setCursor(UI_CURSOR_ARROW);
 		}
 
 		// Set mouse over flag if unset
@@ -1182,6 +1201,28 @@ static bool handle_media_hover(const LLPickInfo& pick)
 	return false;
 }
 
+bool LLToolPie::handleMediaMouseUp()
+{
+	bool result = false;
+	if(mMediaMouseCaptureID.notNull())
+	{
+		// Face media needs to know the mouse went up.
+		viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mMediaMouseCaptureID);
+		if(media_impl)
+		{
+			// This will send a mouseUp event to the plugin using the last known mouse coordinate (from a mouseDown or mouseMove), which is what we want.
+			media_impl->onMouseCaptureLost();
+		}
+		
+		mMediaMouseCaptureID.setNull();	
+
+		setMouseCapture(FALSE);
+
+		result = true;		
+	}	
+	
+	return result;
+}
 
 static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
 {
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 328653d2b84bc17cebb280b2f8318882752bc351..f6a67c13b170310301ddc79754cae31b2550c78b 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -42,9 +42,12 @@ class LLObjectSelection;
 
 class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 {
+	LOG_CLASS(LLToolPie);
 public:
 	LLToolPie( );
 
+	// Virtual functions inherited from LLMouseHandler
+	virtual BOOL		handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
 	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleRightMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask);
@@ -81,9 +84,15 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	BOOL useClickAction		(MASK mask, LLViewerObject* object,LLViewerObject* parent);
 	
 	void showVisualContextMenuEffect();
+
+	bool handleMediaClick(const LLPickInfo& info);
+	bool handleMediaHover(const LLPickInfo& info);
+	bool handleMediaMouseUp();
+
 private:
 	BOOL				mGrabMouseButtonDown;
 	BOOL				mMouseOutsideSlop;				// for this drag, has mouse moved outside slop region
+	LLUUID				mMediaMouseCaptureID;
 	LLPickInfo			mPick;
 	LLPickInfo			mHoverPick;
 	LLPointer<LLViewerObject> mClickActionObject;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 901d0594f12847dcfa1c71ed9130c1c78ed3581e..e7a8ad66050728e32e3387bcc6e9e8f47d4234de 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -37,7 +37,7 @@
 #include "llagent.h"			// teleportViaLocation()
 #include "llcommandhandler.h"
 #include "llfloaterdirectory.h"
-#include "llfloatermediabrowser.h"
+#include "llfloaterhelpbrowser.h"
 #include "llfloaterreg.h"
 #include "llfloaterurldisplay.h"
 #include "llfloaterworldmap.h"
@@ -105,7 +105,7 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
 									   bool trusted_browser)
 {
 	if (url.empty()) return false;
-	if (dispatchHelp(url, right_mouse)) return true;
+	//if (dispatchHelp(url, right_mouse)) return true;
 	if (dispatchApp(url, right_mouse, web, trusted_browser)) return true;
 	if (dispatchRegion(url, right_mouse)) return true;
 
@@ -139,19 +139,6 @@ bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
 	return dispatchCore(url, right_click, web, trusted_browser);
 }
 
-// static
-bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse)
-{
-#if LL_LIBXUL_ENABLED
-	if (LLSLURL::isURLHelp(url))
-	{
-		gViewerHtmlHelp.show();
-		return true;
-	}
-#endif
-	return false;
-}
-
 // static
 bool LLURLDispatcherImpl::dispatchApp(const std::string& url, 
 									  bool right_mouse,
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 51d699c0f7fdf3e1ac71bc5b2c98fa6c47982d5c..2f656479f6a553ff23286d9558a92cc5bf169590 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -65,8 +65,9 @@
 #include "llfloatergodtools.h"
 #include "llfloatergroups.h"
 #include "llfloaterhardwaresettings.h"
-#include "llfloaterhtmlcurrency.h"
+#include "llfloaterhelpbrowser.h"
 #include "llfloatermediabrowser.h"
+#include "llfloatermediasettings.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
 #include "llimfloater.h"
@@ -105,6 +106,7 @@
 #include "llfloaterurldisplay.h"
 #include "llfloatervoicedevicesettings.h"
 #include "llfloaterwater.h"
+#include "llfloaterwhitelistentry.h"
 #include "llfloaterwindlight.h"
 #include "llfloaterworldmap.h"
 #include "llinspectavatar.h"
@@ -164,8 +166,8 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
 	LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
 
+	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	
 	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
-	LLFloaterReg::add("html_simple", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlSimple>);
 
 	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
 	LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
@@ -178,6 +180,7 @@ void LLViewerFloaterReg::registerFloaters()
 	
 	LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
 	LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>);	
+	LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);	
 	LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
 	LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
 	LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
@@ -238,17 +241,13 @@ void LLViewerFloaterReg::registerFloaters()
 	
 	LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>);
 	
+	LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);	
 	LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);	
 
 	// *NOTE: Please keep these alphabetized for easier merges
 	
 	// debug use only
 	LLFloaterReg::add("media_remote_ctrl", "floater_media_remote.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaRemoteCtrl>);
-	
-	// Untested / dangerous - not for release
-#if !LL_RELEASE_FOR_DOWNLOAD
-	LLFloaterReg::add("buy_currency_html", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlCurrency>);
-#endif
 
 	LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving
 }
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0e0727e38250e3fd02b4408eb7f449f0860277f9
--- /dev/null
+++ b/indra/newview/llviewerhelp.cpp
@@ -0,0 +1,125 @@
+/** 
+ * @file llviewerhelp.cpp
+ * @brief Utility functions for the Help system
+ * @author Tofu Linden
+ *
+ * $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 "llviewerprecompiledheaders.h"
+
+#include "llfloaterhelpbrowser.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llviewercontrol.h"
+#include "llversionviewer.h"
+#include "llappviewer.h"
+
+#include "llviewerhelputil.h"
+#include "llviewerhelp.h"
+
+
+//////////////////////////////
+// implement LLHelp interface
+
+void LLViewerHelp::showTopic(const std::string &topic)
+{
+	showHelp();
+	
+	if( gSavedSettings.getBOOL("HelpUseLocal") )
+	{
+		LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+		helpbrowser->navigateToLocalPage( "help-offline" , "index.html" );
+	}
+	else 
+	{
+		const LLOSInfo& osinfo = LLAppViewer::instance()->getOSInfo();
+		std::string helpURL = LLViewerHelpUtil::buildHelpURL( topic, gSavedSettings, osinfo );
+		setRawURL( helpURL );
+	}
+}
+
+std::string LLViewerHelp::defaultTopic()
+{
+	// *hack: to be done properly
+	return "this_is_fallbacktopic";
+}
+
+//////////////////////////////
+// our own interfaces
+
+std::string LLViewerHelp::getTopicFromFocus()
+{
+	// use UI element with viewer's keyboard focus as basis for searching
+	LLUICtrl* focused = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+
+	if (focused)
+	{
+		std::string topic;
+		if (focused->findHelpTopic(topic))
+		{
+			return topic;
+		}
+	}
+
+	// didn't find a help topic in the UI hierarchy for focused
+	// element, return the fallback topic name instead.
+	return defaultTopic();
+}
+
+// static 
+void LLViewerHelp::showHelp()
+{
+	LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+	if (helpbrowser)
+	{
+		BOOL visible = TRUE;
+		BOOL take_focus = TRUE;
+		helpbrowser->setVisible(visible);
+		helpbrowser->setFrontmost(take_focus);
+	}
+	else
+	{
+		llwarns << "Eep, help_browser floater not found" << llendl;
+	}
+}
+
+// static
+void LLViewerHelp::setRawURL(std::string url)
+{
+	LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
+	if (helpbrowser)
+	{
+		helpbrowser->openMedia(url);	
+	}
+	else
+	{
+		llwarns << "Eep, help_browser floater not found" << llendl;
+	}
+}
+
diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h
new file mode 100644
index 0000000000000000000000000000000000000000..17aab6f239738a75de2a2aa53bcd885cb1cf836b
--- /dev/null
+++ b/indra/newview/llviewerhelp.h
@@ -0,0 +1,65 @@
+/** 
+ * @file llviewerhelp.h
+ * @brief Utility functions for the Help system
+ * @author Tofu Linden
+ *
+ * $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_LLVIEWERHELP_H
+#define LL_LLVIEWERHELP_H
+
+// The Help UI lives in llfloaterhelpbrowser, llviewerhelp provides a
+// layer of abstraction that protects help-system-using code from the details of
+// the Help UI floater and how help topics are converted into URLs.
+
+#include "llhelp.h" // our abstract base
+#include "llsingleton.h"
+
+class LLUICtrl;
+
+class LLViewerHelp : public LLHelp, public LLSingleton<LLViewerHelp>
+{
+	friend class LLSingleton<LLViewerHelp>;
+
+ public:
+	/// display the specified help topic in the help viewer
+	/*virtual*/ void showTopic(const std::string &topic);
+
+	/// return default (fallback) topic name suitable for showTopic()
+	/*virtual*/ std::string defaultTopic();
+
+	// return topic derived from viewer UI focus, else default topic
+	std::string getTopicFromFocus();
+
+ private:
+	static void showHelp(); // make sure help UI is visible & raised
+	static void setRawURL(std::string url); // send URL to help UI
+};
+
+#endif // header guard
diff --git a/indra/newview/llviewerhelputil.cpp b/indra/newview/llviewerhelputil.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1555eacdc1d87d25864514ce99ee2aebb25b350
--- /dev/null
+++ b/indra/newview/llviewerhelputil.cpp
@@ -0,0 +1,114 @@
+/** 
+ * @file llviewerhelp.cpp
+ * @brief Utility functions for the Help system
+ * @author Soft Linden
+ *
+ * $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 "llviewerprecompiledheaders.h"
+
+#include "llversionviewer.h"
+
+//#include "llfloaterhelpbrowser.h"
+//#include "llfloaterreg.h"
+//#include "llfocusmgr.h"
+//#include "llviewercontrol.h"
+//#include "llappviewer.h"
+
+#include "llstring.h"
+#include "lluri.h"
+#include "llsys.h"
+
+#include "llcontrol.h"
+
+#include "llviewerhelputil.h"
+
+
+//////////////////////////////////////////////
+// Build a help URL from a topic and formatter
+
+//static
+std::string LLViewerHelpUtil::helpURLEncode( const std::string &component )
+{
+	// Every character rfc3986 allows as unreserved in 2.3, minus the tilde
+	// which we may grant special meaning. Yay.
+	const char* allowed =   
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	"abcdefghijklmnopqrstuvwxyz"
+	"0123456789"
+	"-._";
+	std::string escaped = LLURI::escape(component, allowed);
+	
+	return escaped;
+}
+
+static std::string buildHelpVersion( const U32 ver_int )
+{
+	std::ostringstream ver_str;
+	ver_str << ver_int;
+	return ver_str.str(); // not encoded - numbers are rfc3986-safe
+}
+
+//static
+std::string LLViewerHelpUtil::buildHelpURL( const std::string &topic,
+					    LLControlGroup &savedSettings,
+					    const LLOSInfo &osinfo )
+{
+	std::string helpURL = savedSettings.getString("HelpURLFormat");
+	LLSD substitution;
+	substitution["TOPIC"] = helpURLEncode(topic);
+	
+	substitution["CHANNEL"] = helpURLEncode(savedSettings.getString("VersionChannelName"));
+
+	// *TODO: We should put this version pattern in a central place; this and near
+	// equivalents are replicated in other code - what's a good location?
+	std::ostringstream version;
+	version << LL_VERSION_MAJOR << "."
+	<< LL_VERSION_MINOR << "."
+	<< LL_VERSION_PATCH << "."
+	<< LL_VERSION_BUILD;
+	substitution["VERSION"] = helpURLEncode(version.str());
+	substitution["VERSION_MAJOR"] = buildHelpVersion(LL_VERSION_MAJOR);
+	substitution["VERSION_MINOR"] = buildHelpVersion(LL_VERSION_MINOR);
+	substitution["VERSION_PATCH"] = buildHelpVersion(LL_VERSION_PATCH);
+	substitution["VERSION_BUILD"] = buildHelpVersion(LL_VERSION_BUILD);
+	
+	substitution["OS"] = helpURLEncode(osinfo.getOSStringSimple());
+
+	std::string language = savedSettings.getString("Language");
+	if( language.empty() || language == "default" )
+	{
+		language = savedSettings.getString("SystemLanguage");
+	}
+	substitution["LANGUAGE"] = helpURLEncode(language);
+		
+	LLStringUtil::format(helpURL, substitution);
+
+	return helpURL;
+}
diff --git a/indra/newview/llviewerhelputil.h b/indra/newview/llviewerhelputil.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ee0d96023932988177598c8b170d18229374f68
--- /dev/null
+++ b/indra/newview/llviewerhelputil.h
@@ -0,0 +1,49 @@
+/** 
+ * @file llviewerhelputil.h
+ * @brief Utility functions for the Help system
+ * @author Soft Linden
+ *
+ * $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_LLVIEWERHELPUTIL_H
+#define LL_LLVIEWERHELPUTIL_H
+
+class LLControlGroup;
+class LLOSInfo;
+
+class LLViewerHelpUtil
+{
+ public:
+	static std::string helpURLEncode( const std::string &component );
+	static std::string buildHelpURL( const std::string &topic,
+					 LLControlGroup &savedSettings,
+					 const LLOSInfo &osinfo);
+};
+
+#endif // header guard
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f033d66c1f20772582e86e63032b0abf09b7d21e..100a34291b5ff63ddc921ae9f1cef16937f8fb61 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -35,12 +35,14 @@
 #include "llviewermedia.h"
 #include "llviewermediafocus.h"
 #include "llmimetypes.h"
+#include "llmediaentry.h"
 #include "llviewercontrol.h"
 #include "llviewertexture.h"
 #include "llviewerparcelmedia.h"
 #include "llviewerparcelmgr.h"
 #include "llversionviewer.h"
 #include "llviewertexturelist.h"
+#include "llvovolume.h"
 #include "llpluginclassmedia.h"
 
 #include "llevent.h"		// LLSimpleListener
@@ -95,10 +97,10 @@ bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer )
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event )
+void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLViewerMediaObserver::EMediaEvent event )
 {
+	// Broadcast the event to any observers.
 	observerListType::iterator iter = mObservers.begin();
-
 	while( iter != mObservers.end() )
 	{
 		LLViewerMediaObserver *self = *iter;
@@ -166,55 +168,127 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 };
 typedef std::vector<LLViewerMediaImpl*> impl_list;
 static impl_list sViewerMediaImplList;
+static LLTimer sMediaCreateTimer;
+static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+static void add_media_impl(LLViewerMediaImpl* media)
+{
+	sViewerMediaImplList.push_back(media);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+static void remove_media_impl(LLViewerMediaImpl* media)
+{
+	impl_list::iterator iter = sViewerMediaImplList.begin();
+	impl_list::iterator end = sViewerMediaImplList.end();
+	
+	for(; iter != end; iter++)
+	{
+		if(media == *iter)
+		{
+			sViewerMediaImplList.erase(iter);
+			return;
+		}
+	}
+}
+
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // LLViewerMedia
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // static
-viewer_media_t LLViewerMedia::newMediaImpl(const std::string& media_url,
-														 const LLUUID& texture_id,
-														 S32 media_width, S32 media_height, U8 media_auto_scale,
-														 U8 media_loop,
-														 std::string mime_type)
+viewer_media_t LLViewerMedia::newMediaImpl(
+											 const LLUUID& texture_id,
+											 S32 media_width, 
+											 S32 media_height, 
+											 U8 media_auto_scale,
+											 U8 media_loop)
 {
 	LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id);
 	if(media_impl == NULL || texture_id.isNull())
 	{
 		// Create the media impl
-		media_impl = new LLViewerMediaImpl(media_url, texture_id, media_width, media_height, media_auto_scale, media_loop, mime_type);
-		sViewerMediaImplList.push_back(media_impl);
+		media_impl = new LLViewerMediaImpl(texture_id, media_width, media_height, media_auto_scale, media_loop);
 	}
 	else
 	{
 		media_impl->stop();
 		media_impl->mTextureId = texture_id;
-		media_impl->mMediaURL = media_url;
 		media_impl->mMediaWidth = media_width;
 		media_impl->mMediaHeight = media_height;
 		media_impl->mMediaAutoScale = media_auto_scale;
 		media_impl->mMediaLoop = media_loop;
-		if(! media_url.empty())
-			media_impl->navigateTo(media_url, mime_type, true);
 	}
+
 	return media_impl;
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::removeMedia(LLViewerMediaImpl* media)
-{
-	impl_list::iterator iter = sViewerMediaImplList.begin();
-	impl_list::iterator end = sViewerMediaImplList.end();
+viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self)
+{	
+	// Try to find media with the same media ID
+	viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID());
+
+	bool was_loaded = false;
+	bool needs_navigate = false;
 	
-	for(; iter != end; iter++)
+	if(media_impl)
+	{	
+		was_loaded = media_impl->hasMedia();
+		
+		media_impl->setHomeURL(media_entry->getHomeURL());
+		
+		media_impl->mMediaAutoScale = media_entry->getAutoScale();
+		media_impl->mMediaLoop = media_entry->getAutoLoop();
+		media_impl->mMediaWidth = media_entry->getWidthPixels();
+		media_impl->mMediaHeight = media_entry->getHeightPixels();
+		if (media_impl->mMediaSource)
+		{
+			media_impl->mMediaSource->setAutoScale(media_impl->mMediaAutoScale);
+			media_impl->mMediaSource->setLoop(media_impl->mMediaLoop);
+			media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels());
+		}
+		
+		if((was_loaded || media_entry->getAutoPlay()) && !update_from_self)
+		{
+			if(!media_entry->getCurrentURL().empty())
+			{
+				needs_navigate = (media_entry->getCurrentURL() != previous_url);
+			}
+			else if(!media_entry->getHomeURL().empty())
+			{
+				needs_navigate = (media_entry->getHomeURL() != previous_url);
+			}
+		}
+	}
+	else
 	{
-		if(media == *iter)
+		media_impl = newMediaImpl(
+			media_entry->getMediaID(), 
+			media_entry->getWidthPixels(),
+			media_entry->getHeightPixels(), 
+			media_entry->getAutoScale(), 
+			media_entry->getAutoLoop());
+		
+		media_impl->setHomeURL(media_entry->getHomeURL());
+		
+		if(media_entry->getAutoPlay())
 		{
-			sViewerMediaImplList.erase(iter);
-			return;
+			needs_navigate = true;
 		}
 	}
+	
+	if(media_impl && needs_navigate)
+	{
+		std::string url = media_entry->getCurrentURL();
+		if(url.empty())
+			url = media_entry->getHomeURL();
+			
+		media_impl->navigateTo(url, "", true, true);
+	}
+	
+	return media_impl;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -323,6 +397,36 @@ void LLViewerMedia::setVolume(F32 volume)
 	}
 }
 
+// This is the predicate function used to sort sViewerMediaImplList by priority.
+static inline bool compare_impl_interest(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
+{
+	if(i1->hasFocus())
+	{
+		// The item with user focus always comes to the front of the list, period.
+		return true;
+	}
+	else if(i2->hasFocus())
+	{
+		// The item with user focus always comes to the front of the list, period.
+		return false;
+	}
+	else if(i1->getUsedInUI() && !i2->getUsedInUI())
+	{
+		// i1 is a UI element, i2 is not.  This makes i1 "less than" i2, so it sorts earlier in our list.
+		return true;
+	}
+	else if(i2->getUsedInUI() && !i1->getUsedInUI())
+	{
+		// i2 is a UI element, i1 is not.  This makes i2 "less than" i1, so it sorts earlier in our list.
+		return false;
+	}
+	else
+	{
+		// The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here.
+		return (i1->getInterest() > i2->getInterest());
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::updateMedia()
@@ -334,32 +438,138 @@ void LLViewerMedia::updateMedia()
 	{
 		LLViewerMediaImpl* pimpl = *iter;
 		pimpl->update();
+		pimpl->calculateInterest();
 	}
+		
+	// Sort the static instance list using our interest criteria
+	std::stable_sort(sViewerMediaImplList.begin(), sViewerMediaImplList.end(), compare_impl_interest);
+
+	// Go through the list again and adjust according to priority.
+	iter = sViewerMediaImplList.begin();
+	end = sViewerMediaImplList.end();
+	
+	F64 total_cpu = 0.0f;
+	int impl_count_total = 0;
+	int impl_count_interest_low = 0;
+	int impl_count_interest_normal = 0;
+
+#if 0	
+	LL_DEBUGS("PluginPriority") << "Sorted impls:" << llendl;
+#endif
+
+	U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
+	U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
+	U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
+	F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit");
+	// Setting max_cpu to 0.0 disables CPU usage checking.
+	bool check_cpu_usage = (max_cpu != 0.0f);
+	
+	// Notes on tweakable params:
+	// max_instances must be set high enough to allow the various instances used in the UI (for the help browser, search, etc.) to be loaded.
+	// If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow.
+	
+	for(; iter != end; iter++)
+	{
+		LLViewerMediaImpl* pimpl = *iter;
+		
+		LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+
+		if(impl_count_total > (int)max_instances)
+		{
+			// Hard limit on the number of instances that will be loaded at one time
+			new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;
+		}
+		else if(!pimpl->getVisible())
+		{
+			new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
+		}
+		else if(pimpl->hasFocus())
+		{
+			new_priority = LLPluginClassMedia::PRIORITY_HIGH;
+		}
+		else if(pimpl->getUsedInUI())
+		{
+			new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+		}
+		else
+		{
+			// Look at interest and CPU usage for instances that aren't in any of the above states.
+			
+			// Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture,
+			// turn it down to low instead of normal.  This may downsample for plugins that support it.
+			bool media_is_small = pimpl->getInterest() < (pimpl->getApproximateTextureInterest() / 4);
+			
+			if(pimpl->getInterest() == 0.0f)
+			{
+				// This media is completely invisible, due to being outside the view frustrum or out of range.
+				new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
+			}
+			else if(check_cpu_usage && (total_cpu > max_cpu))
+			{
+				// Higher priority plugins have already used up the CPU budget.  Set remaining ones to slideshow priority.
+				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
+			}
+			else if((impl_count_interest_normal < (int)max_normal) && !media_is_small)
+			{
+				// Up to max_normal inworld get normal priority
+				new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+				impl_count_interest_normal++;
+			}
+			else if (impl_count_interest_low + impl_count_interest_normal < (int)max_low + (int)max_normal)
+			{
+				// The next max_low inworld get turned down
+				new_priority = LLPluginClassMedia::PRIORITY_LOW;
+				impl_count_interest_low++;
+				
+				// Set the low priority size for downsampling to approximately the size the texture is displayed at.
+				{
+					F32 approximate_interest_dimension = fsqrtf(pimpl->getInterest());
+					
+					pimpl->setLowPrioritySizeLimit(llround(approximate_interest_dimension));
+				}
+			}
+			else
+			{
+				// Any additional impls (up to max_instances) get very infrequent time
+				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
+			}
+		}
+		
+		pimpl->setPriority(new_priority);
+
+#if 0		
+		LL_DEBUGS("PluginPriority") << "    " << pimpl 
+			<< ", setting priority to " << new_priority
+			<< (pimpl->hasFocus()?", HAS FOCUS":"") 
+			<< (pimpl->getUsedInUI()?", is UI":"") 
+			<< ", cpu " << pimpl->getCPUUsage() 
+			<< ", interest " << pimpl->getInterest() 
+			<< ", media url " << pimpl->getMediaURL() << llendl;
+#endif
+
+		total_cpu += pimpl->getCPUUsage();
+		impl_count_total++;
+	}
+	
+	LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl;
+
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::cleanupClass()
 {
-	// This is no longer necessary, since the list is no longer smart pointers.
-#if 0
-	while(!sViewerMediaImplList.empty())
-	{
-		sViewerMediaImplList.pop_back();
-	}
-#endif
+	// This is no longer necessary, since sViewerMediaImplList is no longer smart pointers.
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // LLViewerMediaImpl
 //////////////////////////////////////////////////////////////////////////////////////////
-LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url, 
-										  const LLUUID& texture_id, 
+LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id, 
 										  S32 media_width, 
 										  S32 media_height, 
 										  U8 media_auto_scale, 
-										  U8 media_loop,
-										  const std::string& mime_type)
+										  U8 media_loop)
 :	
 	mMediaSource( NULL ),
 	mMovieImageHasMips(false),
@@ -368,13 +578,30 @@ LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url,
 	mMediaHeight(media_height),
 	mMediaAutoScale(media_auto_scale),
 	mMediaLoop(media_loop),
-	mMediaURL(media_url),
-	mMimeType(mime_type),
 	mNeedsNewTexture(true),
 	mSuspendUpdates(false),
-	mVisible(true)
+	mVisible(true),
+	mLastSetCursor( UI_CURSOR_ARROW ),
+	mMediaNavState( MEDIANAVSTATE_NONE ),
+	mInterest(0.0f),
+	mUsedInUI(false),
+	mHasFocus(false),
+	mPriority(LLPluginClassMedia::PRIORITY_UNLOADED),
+	mDoNavigateOnLoad(false),
+	mDoNavigateOnLoadServerRequest(false),
+	mIsUpdated(false)
 { 
-	createMediaSource();
+	
+	add_media_impl(this);
+	
+	// connect this media_impl to the media texture, creating it if it doesn't exist.0
+	// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
+	LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
+	if(media_tex)
+	{
+		media_tex->setMediaImpl();
+	}
+
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -386,7 +613,26 @@ LLViewerMediaImpl::~LLViewerMediaImpl()
 	}
 	
 	destroyMediaSource();
-	LLViewerMedia::removeMedia(this);
+	
+	LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
+
+	remove_media_impl(this);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
+{
+	// Broadcast to observers using the superclass version
+	LLViewerMediaEventEmitter::emitEvent(plugin, event);
+	
+	// If this media is on one or more LLVOVolume objects, tell them about the event as well.
+	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
+	while(iter != mObjectList.end())
+	{
+		LLVOVolume *self = *iter;
+		++iter;
+		self->mediaEvent(this, plugin, event);
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -396,11 +642,7 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
 	{
 		if(! initializePlugin(mime_type))
 		{
-			LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL;
-			LLSD args;
-			args["MIME_TYPE"] = mime_type;
-			LLNotifications::instance().add("NoPlugin", args);
-
+			// This may be the case where the plugin's priority is PRIORITY_UNLOADED
 			return false;
 		}
 	}
@@ -412,29 +654,42 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::createMediaSource()
 {
-	if(! mMediaURL.empty())
+	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
 	{
-		navigateTo(mMediaURL, mMimeType, true);
+		// This media shouldn't be created yet.
+		return;
 	}
-	else if(! mMimeType.empty())
+	
+	if(mDoNavigateOnLoad)
 	{
-		initializeMedia(mMimeType);
+		if(! mMediaURL.empty())
+		{
+			navigateTo(mMediaURL, mMimeType, false, mDoNavigateOnLoadServerRequest);
+		}
+		else if(! mMimeType.empty())
+		{
+			initializeMedia(mMimeType);
+		}
 	}
-	
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::destroyMediaSource()
 {
 	mNeedsNewTexture = true;
-	if(! mMediaSource)
+
+	// Tell the viewer media texture it's no longer active
+	LLViewerMediaTexture* oldImage = LLViewerTextureManager::findMediaTexture( mTextureId );
+	if (oldImage)
 	{
-		return;
+		oldImage->setPlaying(FALSE) ;
 	}
-	// Restore the texture
-	updateMovieImage(LLUUID::null, false);
-	delete mMediaSource;
-	mMediaSource = NULL;
+
+	if(mMediaSource)
+	{
+		delete mMediaSource;
+		mMediaSource = NULL;
+	}	
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -487,6 +742,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		}
 	}
 	
+	LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
+	LLSD args;
+	args["MIME_TYPE"] = media_type;
+	LLNotifications::instance().add("NoPlugin", args);
+
 	return NULL;
 }							
 
@@ -506,7 +766,15 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 	// and unconditionally set the mime type
 	mMimeType = media_type;
 
-	LLPluginClassMedia* media_source = newSourceFromMediaType(media_type, this, mMediaWidth, mMediaHeight);
+	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
+	{
+		// This impl should not be loaded at this time.
+		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
+		
+		return false;
+	}
+
+	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight);
 	
 	if (media_source)
 	{
@@ -543,13 +811,11 @@ void LLViewerMediaImpl::play()
 	{
 	 	if(!initializePlugin(mMimeType))
 		{
-			// Plugin failed initialization... should assert or something
+			// This may be the case where the plugin's priority is PRIORITY_UNLOADED
 			return;
 		}
 	}
 	
-	// updateMovieImage(mTextureId, true);
-
 	mMediaSource->loadURI( mMediaURL );
 	if(/*mMediaSource->pluginSupportsMediaTime()*/ true)
 	{
@@ -606,6 +872,8 @@ void LLViewerMediaImpl::setVolume(F32 volume)
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::focus(bool focus)
 {
+	mHasFocus = focus;
+	
 	if (mMediaSource)
 	{
 		// call focus just for the hell of it, even though this apopears to be a nop
@@ -620,12 +888,20 @@ void LLViewerMediaImpl::focus(bool focus)
 	}
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::hasFocus() const
+{
+	// FIXME: This might be able to be a bit smarter by hooking into LLViewerMediaFocus, etc.
+	return mHasFocus;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::mouseDown(S32 x, S32 y)
 {
 	scaleMouse(&x, &y);
 	mLastMouseX = x;
 	mLastMouseY = y;
+//	llinfos << "mouse down (" << x << ", " << y << ")" << llendl;
 	if (mMediaSource)
 	{
 		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, x, y, 0);
@@ -638,6 +914,7 @@ void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
 	scaleMouse(&x, &y);
 	mLastMouseX = x;
 	mLastMouseY = y;
+//	llinfos << "mouse up (" << x << ", " << y << ")" << llendl;
 	if (mMediaSource)
 	{
 		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, x, y, 0);
@@ -647,15 +924,47 @@ void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::mouseMove(S32 x, S32 y)
 {
-	scaleMouse(&x, &y);
+    scaleMouse(&x, &y);
 	mLastMouseX = x;
 	mLastMouseY = y;
+//	llinfos << "mouse move (" << x << ", " << y << ")" << llendl;
 	if (mMediaSource)
 	{
 		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, x, y, 0);
 	}
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords)
+{
+	if(mMediaSource)
+	{		
+		mouseDown(
+			llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+			llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+	}
+}
+
+void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords)
+{
+	if(mMediaSource)
+	{		
+		mouseUp(
+			llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+			llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+	}
+}
+
+void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords)
+{
+	if(mMediaSource)
+	{		
+		mouseMove(
+			llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
+			llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()));
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::mouseLeftDoubleClick(S32 x, S32 y)
 {
@@ -694,6 +1003,10 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::navigateHome()
 {
+	mMediaURL = mHomeURL;
+	mDoNavigateOnLoad = !mMediaURL.empty();
+	mDoNavigateOnLoadServerRequest = false;
+	
 	if(mMediaSource)
 	{
 		mMediaSource->loadURI( mHomeURL );
@@ -701,17 +1014,43 @@ void LLViewerMediaImpl::navigateHome()
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type)
+void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type, bool server_request)
 {
+	if(server_request)
+	{
+		setNavState(MEDIANAVSTATE_SERVER_SENT);
+	}
+	else
+	{
+		setNavState(MEDIANAVSTATE_NONE);
+	}
+	
+	// Always set the current URL.
+	mMediaURL = url;
+	
+	// If the current URL is not null, make the instance do a navigate on load.
+	mDoNavigateOnLoad = !mMediaURL.empty();
+
+	// and if this was a server request, the navigate on load will also need to be one.
+	mDoNavigateOnLoadServerRequest = server_request;
+
+	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
+	{
+		// This impl should not be loaded at this time.
+		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
+		
+		return;
+	}
+
 	if(rediscover_type)
 	{
 
-		LLURI uri(url);
+		LLURI uri(mMediaURL);
 		std::string scheme = uri.scheme();
 
 		if(scheme.empty() || "http" == scheme || "https" == scheme)
 		{
-			LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this));
+			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this));
 		}
 		else if("data" == scheme || "file" == scheme || "about" == scheme)
 		{
@@ -719,7 +1058,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
 			// We use "data" internally for a text/html url for loading the login screen
 			if(initializeMedia("text/html"))
 			{
-				mMediaSource->loadURI( url );
+				mMediaSource->loadURI( mMediaURL );
 			}
 		}
 		else
@@ -727,24 +1066,23 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
 			// This catches 'rtsp://' urls
 			if(initializeMedia(scheme))
 			{
-				mMediaSource->loadURI( url );
+				mMediaSource->loadURI( mMediaURL );
 			}
 		}
 	}
 	else if (mMediaSource)
 	{
-		mMediaSource->loadURI( url );
+		mMediaSource->loadURI( mMediaURL );
 	}
 	else if(initializeMedia(mime_type) && mMediaSource)
 	{
-		mMediaSource->loadURI( url );
+		mMediaSource->loadURI( mMediaURL );
 	}
 	else
 	{
 		LL_WARNS("Media") << "Couldn't navigate to: " << url << " as there is no media type for: " << mime_type << LL_ENDL;
 		return;
 	}
-	mMediaURL = url;
 
 }
 
@@ -806,49 +1144,27 @@ bool LLViewerMediaImpl::canNavigateBack()
 	return result;
 }
 
-
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
+void LLViewerMediaImpl::update()
 {
-	// IF the media image hasn't changed, do nothing
-	if (mTextureId == uuid)
-	{
-		return;
-	}
-	// If we have changed media uuid, restore the old one
-	if (!mTextureId.isNull())
+	if(mMediaSource == NULL)
 	{
-		LLViewerMediaTexture* old_image = LLViewerTextureManager::findMediaTexture( mTextureId );
-		if (old_image)
+		if(mPriority != LLPluginClassMedia::PRIORITY_UNLOADED)
 		{
-			old_image->setPlaying(FALSE);
-			LLViewerTexture* original_texture = old_image->getOldTexture();
-			if(original_texture)
+			// This media may need to be loaded.
+			if(sMediaCreateTimer.hasExpired())
 			{
-				old_image->switchToTexture(original_texture);
+				LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL;
+				createMediaSource();
+				sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY);
+			}
+			else
+			{
+				LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL;
 			}
 		}
 	}
-	// If the movie is playing, set the new media image
-	if (active && !uuid.isNull())
-	{
-		LLViewerMediaTexture* viewerImage = LLViewerTextureManager::findMediaTexture( uuid );
-		if( viewerImage )
-		{
-			mTextureId = uuid;
-			
-			// Can't use mipmaps for movies because they don't update the full image
-			mMovieImageHasMips = viewerImage->getUseMipMaps();
-			viewerImage->reinit(FALSE);
-			// FIXME
-//			viewerImage->mIsMediaTexture = TRUE;
-		}
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::update()
-{
+	
 	if(mMediaSource == NULL)
 	{
 		return;
@@ -877,6 +1193,10 @@ void LLViewerMediaImpl::update()
 	if(placeholder_image)
 	{
 		LLRect dirty_rect;
+		
+		// Since we're updating this texture, we know it's playing.  Tell the texture to do its replacement magic so it gets rendered.
+		placeholder_image->setPlaying(TRUE);
+
 		if(mMediaSource->getDirty(&dirty_rect))
 		{
 			// Constrain the dirty rect to be inside the texture
@@ -930,12 +1250,11 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
 	
 	if (mNeedsNewTexture 
 		|| placeholder_image->getUseMipMaps()
-//		|| ! placeholder_image->getType() == LLViewerTexture::MEDIA_TEXTURE
 		|| placeholder_image->getWidth() != mMediaSource->getTextureWidth()
 		|| placeholder_image->getHeight() != mMediaSource->getTextureHeight())
 	{
-		llinfos << "initializing media placeholder" << llendl;
-		llinfos << "movie image id " << mTextureId << llendl;
+		LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL;
+		LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL;
 
 		int texture_width = mMediaSource->getTextureWidth();
 		int texture_height = mMediaSource->getTextureHeight();
@@ -960,9 +1279,6 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
 
 		placeholder_image->createGLTexture(discard_level, raw);
 
-		// placeholder_image->setExplicitFormat()
-		placeholder_image->setUseMipMaps(FALSE);
-
 		// MEDIAOPT: set this dynamically on play/stop
 		// FIXME
 //		placeholder_image->mIsMediaTexture = true;
@@ -996,11 +1312,6 @@ void LLViewerMediaImpl::setVisible(bool visible)
 			createMediaSource();
 		}
 	}
-	
-	if(mMediaSource)
-	{
-		mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN);
-	}
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1059,7 +1370,7 @@ bool LLViewerMediaImpl::hasMedia()
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event)
+void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
 {
 	switch(event)
 	{
@@ -1070,11 +1381,77 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClass
 			LLNotifications::instance().add("MediaPluginFailed", args);
 		}
 		break;
+		
+		case MEDIA_EVENT_CURSOR_CHANGED:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << plugin->getCursorName() << LL_ENDL;
+
+			std::string cursor = plugin->getCursorName();
+			
+			if(cursor == "arrow")
+				mLastSetCursor = UI_CURSOR_ARROW;
+			else if(cursor == "ibeam")
+				mLastSetCursor = UI_CURSOR_IBEAM;
+			else if(cursor == "splith")
+				mLastSetCursor = UI_CURSOR_SIZEWE;
+			else if(cursor == "splitv")
+				mLastSetCursor = UI_CURSOR_SIZENS;
+			else if(cursor == "hand")
+				mLastSetCursor = UI_CURSOR_HAND;
+			else // for anything else, default to the arrow
+				mLastSetCursor = UI_CURSOR_ARROW;
+		}
+		break;
+
+		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
+		{
+			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
+
+			if(getNavState() == MEDIANAVSTATE_SERVER_SENT)
+			{
+				setNavState(MEDIANAVSTATE_SERVER_BEGUN);
+			}
+			else
+			{
+				setNavState(MEDIANAVSTATE_BEGUN);
+			}
+		}
+		break;
+
+		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
+		{
+			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL;
+			setNavState(MEDIANAVSTATE_NONE);
+		}
+		break;
+		
+		case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
+		{
+			LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL;
+
+			if(getNavState() == MEDIANAVSTATE_BEGUN)
+			{
+				setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED);
+			}
+			else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN)
+			{
+				setNavState(MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED);
+			}
+			else
+			{
+				// Don't track redirects.
+				setNavState(MEDIANAVSTATE_NONE);
+			}
+		}
+		break;
+
+		
 		default:
 		break;
 	}
+
 	// Just chain the event to observers.
-	emitEvent(self, event);
+	emitEvent(plugin, event);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1137,6 +1514,146 @@ LLViewerMediaImpl::canPaste() const
 		return FALSE;
 }
 
+void LLViewerMediaImpl::setUpdated(BOOL updated)
+{
+	mIsUpdated = updated ;
+}
+
+BOOL LLViewerMediaImpl::isUpdated()
+{
+	return mIsUpdated ;
+}
+
+void LLViewerMediaImpl::calculateInterest()
+{
+	LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
+	
+	if(texture != NULL)
+	{
+		mInterest = texture->getMaxVirtualSize();
+	}
+	else
+	{
+		// I don't think this case should ever be hit.
+		LL_WARNS("Plugin") << "no texture!" << LL_ENDL;
+		mInterest = 0.0f;
+	}
+}
+
+F64 LLViewerMediaImpl::getApproximateTextureInterest()
+{
+	F64 result = 0.0f;
+	
+	if(mMediaSource)
+	{
+		result = mMediaSource->getFullWidth();
+		result *= mMediaSource->getFullHeight();
+	}
+	
+	return result;
+}
+
+void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
+{
+	mUsedInUI = used_in_ui; 
+	
+	// HACK: Force elements used in UI to load right away.
+	// This fixes some issues where UI code that uses the browser instance doesn't expect it to be unloaded.
+	if(mUsedInUI && (mPriority == LLPluginClassMedia::PRIORITY_UNLOADED))
+	{
+		if(getVisible())
+		{
+			mPriority = LLPluginClassMedia::PRIORITY_NORMAL;
+		}
+		else
+		{
+			mPriority = LLPluginClassMedia::PRIORITY_HIDDEN;
+		}
+
+		createMediaSource();
+	}
+};
+
+F64 LLViewerMediaImpl::getCPUUsage() const
+{
+	F64 result = 0.0f;
+	
+	if(mMediaSource)
+	{
+		result = mMediaSource->getCPUUsage();
+	}
+	
+	return result;
+}
+
+void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
+{
+	mPriority = priority;
+	
+	if(priority == LLPluginClassMedia::PRIORITY_UNLOADED)
+	{
+		if(mMediaSource)
+		{
+			// Need to unload the media source
+			destroyMediaSource();
+		}
+	}
+
+	if(mMediaSource)
+	{
+		mMediaSource->setPriority(mPriority);
+	}
+	
+	// NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update().
+}
+
+void LLViewerMediaImpl::setLowPrioritySizeLimit(int size)
+{
+	if(mMediaSource)
+	{
+		mMediaSource->setLowPrioritySizeLimit(size);
+	}
+}
+
+void LLViewerMediaImpl::setNavState(EMediaNavState state)
+{
+	mMediaNavState = state;
+	
+	switch (state) 
+	{
+		case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << llendl; break;
+		case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << llendl; break;
+		case MEDIANAVSTATE_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED" << llendl; break;
+		case MEDIANAVSTATE_SERVER_SENT: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_SENT" << llendl; break;
+		case MEDIANAVSTATE_SERVER_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_BEGUN" << llendl; break;
+		case MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED" << llendl; break;
+	}
+}
+
+
+void LLViewerMediaImpl::addObject(LLVOVolume* obj) 
+{
+	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
+	for(; iter != mObjectList.end() ; ++iter)
+	{
+		if(*iter == obj)
+		{
+			return ; //already in the list.
+		}
+	}
+
+	mObjectList.push_back(obj) ;
+}
+	
+void LLViewerMediaImpl::removeObject(LLVOVolume* obj) 
+{
+	mObjectList.remove(obj) ;	
+}
+	
+const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const 
+{
+	return &mObjectList ;
+}
 
 //////////////////////////////////////////////////////////////////////////////////////////
 //static
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 9a613943830661a85204b63018846d48c81e4277..775f72d56f5c66fc1d51d15500d560e323cc5865 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -41,9 +41,13 @@
 
 #include "llviewermediaobserver.h"
 
+#include "llpluginclassmedia.h"
+
 class LLViewerMediaImpl;
 class LLUUID;
 class LLViewerMediaTexture;
+class LLMediaEntry;
+class LLVOVolume ;
 
 typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
 ///////////////////////////////////////////////////////////////////////////////
@@ -55,7 +59,7 @@ class LLViewerMediaEventEmitter
 
 	bool addObserver( LLViewerMediaObserver* subject );
 	bool remObserver( LLViewerMediaObserver* subject );
-	void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
+	virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
 
 private:
 	typedef std::list< LLViewerMediaObserver* > observerListType;
@@ -69,15 +73,13 @@ class LLViewerMedia
 		// Special case early init for just web browser component
 		// so we can show login screen.  See .cpp file for details. JC
 
-		static viewer_media_t newMediaImpl(const std::string& media_url,
-												const LLUUID& texture_id,
-												S32 media_width, 
-												S32 media_height, 
-												U8 media_auto_scale,
-												U8 media_loop,
-												std::string mime_type = "none/none");
+		static viewer_media_t newMediaImpl(const LLUUID& texture_id,
+												S32 media_width = 0, 
+												S32 media_height = 0, 
+												U8 media_auto_scale = false,
+												U8 media_loop = false);
 
-		static void removeMedia(LLViewerMediaImpl* media);
+		static viewer_media_t updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self);
 		static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id);
 		static std::string getCurrentUserAgent();
 		static void updateBrowserUserAgent();
@@ -102,15 +104,18 @@ class LLViewerMediaImpl
 	LOG_CLASS(LLViewerMediaImpl);
 public:
 
-	LLViewerMediaImpl(const std::string& media_url,
+	LLViewerMediaImpl(
 		const LLUUID& texture_id,
 		S32 media_width, 
 		S32 media_height, 
 		U8 media_auto_scale,
-		U8 media_loop,
-		const std::string& mime_type);
+		U8 media_loop);
 
 	~LLViewerMediaImpl();
+	
+	// Override inherited version from LLViewerMediaEventEmitter 
+	virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
+
 	void createMediaSource();
 	void destroyMediaSource();
 	void setMediaType(const std::string& media_type);
@@ -126,36 +131,44 @@ class LLViewerMediaImpl
 	void seek(F32 time);
 	void setVolume(F32 volume);
 	void focus(bool focus);
+	// True if the impl has user focus.
+	bool hasFocus() const;
 	void mouseDown(S32 x, S32 y);
 	void mouseUp(S32 x, S32 y);
 	void mouseMove(S32 x, S32 y);
+	void mouseDown(const LLVector2& texture_coords);
+	void mouseUp(const LLVector2& texture_coords);
+	void mouseMove(const LLVector2& texture_coords);
 	void mouseLeftDoubleClick(S32 x,S32 y );
 	void mouseCapture();
 
 	void navigateHome();
-	void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false);
+	void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false, bool server_request = false);
 	void navigateStop();
 	bool handleKeyHere(KEY key, MASK mask);
 	bool handleUnicodeCharHere(llwchar uni_char);
 	bool canNavigateForward();
 	bool canNavigateBack();
 	std::string getMediaURL() { return mMediaURL; }
-	std::string getMediaHomeURL() { return mHomeURL; }
+	std::string getHomeURL() { return mHomeURL; }
+    void setHomeURL(const std::string& home_url) { mHomeURL = home_url; };
 	std::string getMimeType() { return mMimeType; }
 	void scaleMouse(S32 *mouse_x, S32 *mouse_y);
 
 	void update();
-	void updateMovieImage(const LLUUID& image_id, BOOL active);
 	void updateImagesMediaStreams();
 	LLUUID getMediaTextureID();
 	
 	void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; };
 	void setVisible(bool visible);
+	bool getVisible() const { return mVisible; };
 
 	bool isMediaPlaying();
 	bool isMediaPaused();
 	bool hasMedia();
 
+	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);
 
@@ -191,7 +204,7 @@ class LLViewerMediaImpl
 	/*virtual*/ BOOL hasMouseCapture() { return gFocusMgr.getMouseCapture() == this; };
 
 	// Inherited from LLPluginClassMediaOwner
-	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
+	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
 
 	// LLEditMenuHandler overrides
 	/*virtual*/ void	cut();
@@ -203,6 +216,45 @@ class LLViewerMediaImpl
 	/*virtual*/ void	paste();
 	/*virtual*/ BOOL	canPaste() const;
 	
+	void addObject(LLVOVolume* obj) ;
+	void removeObject(LLVOVolume* obj) ;
+	const std::list< LLVOVolume* >* getObjectList() const ;
+	void setUpdated(BOOL updated) ;
+	BOOL isUpdated() ;
+	
+	// Updates the "interest" value in this object
+	void calculateInterest();
+	F64 getInterest() const { return mInterest; };
+	F64 getApproximateTextureInterest();
+	
+	// Mark this object as being used in a UI panel instead of on a prim
+	// This will be used as part of the interest sorting algorithm.
+	void setUsedInUI(bool used_in_ui);
+	bool getUsedInUI() const { return mUsedInUI; };
+	
+	F64 getCPUUsage() const;
+	
+	void setPriority(LLPluginClassMedia::EPriority priority);
+	LLPluginClassMedia::EPriority getPriority() { return mPriority; };
+
+	void setLowPrioritySizeLimit(int size);
+	
+	typedef enum 
+	{
+		MEDIANAVSTATE_NONE,								// State is outside what we need to track for navigation.
+		MEDIANAVSTATE_BEGUN,							// a MEDIA_EVENT_NAVIGATE_BEGIN has been received which was not server-directed
+		MEDIANAVSTATE_FIRST_LOCATION_CHANGED,			// first LOCATION_CHANGED event after a non-server-directed BEGIN
+		MEDIANAVSTATE_SERVER_SENT,						// server-directed nav has been requested, but MEDIA_EVENT_NAVIGATE_BEGIN hasn't been received yet
+		MEDIANAVSTATE_SERVER_BEGUN,						// MEDIA_EVENT_NAVIGATE_BEGIN has been received which was server-directed
+		MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED		// first LOCATION_CHANGED event after a server-directed BEGIN
+		
+	}EMediaNavState;
+    
+	// Returns the current nav state of the media.
+	// note that this will be updated BEFORE listeners and objects receive media messages 
+	EMediaNavState getNavState() { return mMediaNavState; }
+	void setNavState(EMediaNavState state);
+	
 public:
 	// a single media url with some data and an impl.
 	LLPluginClassMedia* mMediaSource;
@@ -220,7 +272,19 @@ class LLViewerMediaImpl
 	bool mNeedsNewTexture;
 	bool mSuspendUpdates;
 	bool mVisible;
+	ECursorType mLastSetCursor;
+	EMediaNavState mMediaNavState;
+	F64 mInterest;
+	bool mUsedInUI;
+	bool mHasFocus;
+	LLPluginClassMedia::EPriority mPriority;
+	bool mDoNavigateOnLoad;
+	bool mDoNavigateOnLoadServerRequest;
+
 
+private:
+	BOOL mIsUpdated ;
+	std::list< LLVOVolume* > mObjectList ;
 
 private:
 	LLViewerMediaTexture *updatePlaceholderImage();
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index e7576d5c7672a502539cb77779c2a1b01ccfa11a..f9377ab37bb821f6e06b0d07c88cbbf3fb51d5b2 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -47,6 +47,7 @@
 #include "llparcel.h"
 #include "llviewerparcelmgr.h"
 #include "llweb.h"
+#include "llmediaentry.h"
 //
 // LLViewerMediaFocus
 //
@@ -91,14 +92,38 @@ void LLViewerMediaFocus::cleanupClass()
 void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl )
 {
 	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+	if(mMediaImpl.notNull())
+	{
+		mMediaImpl->focus(false);
+	}
+
 	if (b && media_impl.notNull())
 	{
+		bool face_auto_zoom = false;
 		mMediaImpl = media_impl;
+		mMediaImpl->focus(true);
+
 		LLSelectMgr::getInstance()->deselectAll();
 		LLSelectMgr::getInstance()->selectObjectOnly(objectp, face);
 
+		if(objectp.notNull())
+		{
+			LLTextureEntry* tep = objectp->getTE(face);
+			if(! tep->hasMedia())
+			{
+				// Error condition
+			}
+			LLMediaEntry* mep = tep->getMediaData();
+			face_auto_zoom = mep->getAutoZoom();
+			if(! mep->getAutoPlay())
+			{
+				std::string url = mep->getCurrentURL().empty() ? mep->getHomeURL() : mep->getCurrentURL();
+				media_impl->navigateTo(url, "", true);
+			}
+		}
 		mFocus = LLSelectMgr::getInstance()->getSelection();
-		if(mMediaHUD.get() && ! parcel->getMediaPreventCameraZoom())
+		if(mMediaHUD.get() && face_auto_zoom && ! parcel->getMediaPreventCameraZoom())
 		{
 			mMediaHUD.get()->resetZoomLevel();
 			mMediaHUD.get()->nextZoomLevel();
@@ -108,6 +133,7 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
 			gFocusMgr.setKeyboardFocus(this);
 		}
 		mObjectID = objectp->getID();
+		mObjectFace = face;
 		// LLViewerMedia::addObserver(this, mObjectID);
 
 
@@ -133,6 +159,8 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
 
 		// and null out the media impl
 		mMediaImpl = NULL;
+		mObjectID = LLUUID::null;
+		mObjectFace = 0;
 	}
 	if(mMediaHUD.get())
 	{
@@ -230,6 +258,12 @@ void LLViewerMediaFocus::setMouseOverFlag(bool b, viewer_media_t media_impl)
 			gHUDView->addChild(media_hud);	
 		}
 		mMediaHUD.get()->setMediaImpl(media_impl);
+
+		if(mMediaImpl.notNull() && (mMediaImpl != media_impl))
+		{
+			mMediaImpl->focus(false);
+		}
+
 		mMediaImpl = media_impl;
 	}
 	mMouseOverFlag = b;
@@ -356,3 +390,8 @@ F32 LLViewerMediaFocus::getBBoxAspectRatio(const LLBBox& bbox, const LLVector3&
 	// Return the aspect ratio.
 	return *width / *height;
 }
+
+bool LLViewerMediaFocus::isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face)
+{
+	return objectp->getID() == mObjectID && face == mObjectFace;
+}
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index a078d24b6a7f123b34847e5ec92f66f24605fa0c..2688a8b7087d6827fa70283b0ab1591ca18feaab 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -72,6 +72,9 @@ class LLViewerMediaFocus :
 	void setPickInfo(LLPickInfo pick_info) { mPickInfo = pick_info; }
 	F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
 
+	// TODO: figure out why selection mgr hates me
+	bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face);
+
 protected:
 	/*virtual*/ void	onFocusReceived();
 	/*virtual*/ void	onFocusLost();
@@ -83,6 +86,7 @@ class LLViewerMediaFocus :
 	LLPickInfo mPickInfo;
 	LLHandle<LLPanelMediaHUD> mMediaHUD;
 	LLUUID mObjectID;
+	S32 mObjectFace;
 	viewer_media_t mMediaImpl;
 };
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a0bd5f301b0e7f07632c5819c598d1d848db0077..12253455a39fba40c1768123bb3ccba328d5439c 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -103,9 +103,6 @@
 #include "llfloatergodtools.h"
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
-#include "llfloaterhtmlcurrency.h"
-#include "llfloatermediabrowser.h"			// gViewerHtmlHelp
-#include "llfloaterhtmlsimple.h"
 #include "llfloaterhud.h"
 #include "llfloaterinspect.h"
 #include "llfloaterlagmeter.h"
@@ -182,6 +179,7 @@
 #include "lluuid.h"
 #include "llviewercamera.h"
 #include "llviewergenericmessage.h"
+#include "llviewerhelp.h"
 #include "llviewertexturelist.h"	// gTextureList
 #include "llviewerinventory.h"
 #include "llviewermenufile.h"	// init_menu_file()
@@ -375,7 +373,6 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
 void dump_select_mgr(void*);
 
 void dump_inventory(void*);
-void edit_ui(void*);
 void toggle_visibility(void*);
 BOOL get_visibility(void*);
 
@@ -1247,21 +1244,6 @@ class LLAdvancedBuyCurrencyTest : public view_listener_t
 };
 
 
-////////////////////////
-// TOGGLE EDITABLE UI //
-////////////////////////
-
-
-class LLAdvancedToggleEditableUI : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		edit_ui(NULL);
-		return true;
-	}
-};
-
-	
 /////////////////////
 // DUMP SELECT MGR //
 /////////////////////
@@ -5587,11 +5569,6 @@ class LLObjectEnableSitOrStand : public view_listener_t
 	}
 };
 
-void edit_ui(void*)
-{
-	LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled());
-}
-
 void dump_select_mgr(void*)
 {
 	LLSelectMgr::getInstance()->dump();
@@ -5649,8 +5626,8 @@ class LLShowFloater : public view_listener_t
 		}
 		else if (floater_name == "help f1")
 		{
-			llinfos << "Spawning HTML help window" << llendl;
-			gViewerHtmlHelp.show();
+			LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+			vhelp->showTopic(vhelp->getTopicFromFocus());
 		}
 		else if (floater_name == "complaint reporter")
 		{
@@ -7689,6 +7666,19 @@ class LLHelpShowFirstTimeTip : public view_listener_t
 	}
 };
 
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
+{
+	static LLMenuGL*	show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
+			gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	if(gMenuHolder->hasVisibleMenu())
+	{
+		gMenuHolder->hideMenus();
+	}
+	show_navbar_context_menu->buildDrawLabels();
+	show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
+	LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
+}
+
 void initialize_menus()
 {
 	// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
@@ -7886,7 +7876,6 @@ void initialize_menus()
 	// Advanced > UI
 	view_listener_t::addMenu(new LLAdvancedWebBrowserTest(), "Advanced.WebBrowserTest");
 	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
-	view_listener_t::addMenu(new LLAdvancedToggleEditableUI(), "Advanced.ToggleEditableUI");
 	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
 	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
 	view_listener_t::addMenu(new LLAdvancedDumpFocusHolder(), "Advanced.DumpFocusHolder");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index cf482266d6c6d6950348679479ca7ac99abb7b5d..dd6aac2dd3df08554e9d78e019985004bcc412c3 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -52,6 +52,7 @@ void show_debug_menus(); // checks for if menus should be shown first.
 void toggle_debug_menus(void*);
 void show_context_menu( S32 x, S32 y, MASK mask );
 void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
 BOOL enable_save_into_inventory(void*);
 void handle_reset_view();
 void handle_cut(void*);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index d3d5f060e1fe13d8003bea3493d5410bc119197a..05011a1568ad3f69579aa86d5e5546f6c229f707 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -47,6 +47,7 @@
 #include "llframetimer.h"
 #include "llinventory.h"
 #include "llmaterialtable.h"
+#include "llmediadataresponder.h"
 #include "llmutelist.h"
 #include "llnamevalue.h"
 #include "llprimitive.h"
@@ -100,6 +101,8 @@
 #include "llvowlsky.h"
 #include "llmanip.h"
 #include "lltrans.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
 
 //#define DEBUG_UPDATE_TYPE
 
@@ -470,6 +473,7 @@ void LLViewerObject::cleanupVOClasses()
 	LLVOWater::cleanupClass();
 	LLVOTree::cleanupClass();
 	LLVOAvatar::cleanupClass();
+	LLVOVolume::cleanupClass();
 }
 
 // Replaces all name value pairs with data from \n delimited list
@@ -700,6 +704,42 @@ void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
 	}
 }
 
+U32 LLViewerObject::checkMediaURL(const std::string &media_url)
+{
+    U32 retval = (U32)0x0;
+    if (!mMedia && !media_url.empty())
+    {
+        retval |= MEDIA_URL_ADDED;
+        mMedia = new LLViewerObjectMedia;
+        mMedia->mMediaURL = media_url;
+        mMedia->mMediaType = LLViewerObject::MEDIA_SET;
+        mMedia->mPassedWhitelist = FALSE;
+    }
+    else if (mMedia)
+    {
+        if (media_url.empty())
+        {
+            retval |= MEDIA_URL_REMOVED;
+            delete mMedia;
+            mMedia = NULL;
+        }
+        else if (mMedia->mMediaURL != media_url) // <-- This is an optimization.  If they are equal don't bother with below's test.
+        {
+            /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
+                   LLTextureEntry::getVersionFromMediaVersionString(media_url) == 
+                        LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
+			*/
+            {
+                // If the media URL is different and WE were not the one who
+                // changed it, mark dirty.
+                retval |= MEDIA_URL_UPDATED;
+            }
+            mMedia->mMediaURL = media_url;
+            mMedia->mPassedWhitelist = FALSE;
+        }
+    }
+    return retval;
+}
 
 U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 					 void **user_data,
@@ -1045,35 +1085,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 
 				std::string media_url;
 				mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
-				//if (!media_url.empty())
-				//{
-				//	llinfos << "WEBONPRIM media_url " << media_url << llendl;
-				//}
-				if (!mMedia && !media_url.empty())
-				{
-					retval |= MEDIA_URL_ADDED;
-					mMedia = new LLViewerObjectMedia;
-					mMedia->mMediaURL = media_url;
-					mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
-					mMedia->mPassedWhitelist = FALSE;
-				}
-				else if (mMedia)
-				{
-					if (media_url.empty())
-					{
-						retval |= MEDIA_URL_REMOVED;
-						delete mMedia;
-						mMedia = NULL;
-					}
-					else if (mMedia->mMediaURL != media_url)
-					{
-						// We just added or changed a web page.
-						retval |= MEDIA_URL_UPDATED;
-						mMedia->mMediaURL = media_url;
-						mMedia->mPassedWhitelist = FALSE;
-					}
-				}
-
+                retval |= checkMediaURL(media_url);
+                
 				//
 				// Unpack particle system data
 				//
@@ -1456,31 +1469,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 					mText = NULL;
 				}
 
+                std::string media_url;
 				if (value & 0x200)
 				{
-					std::string media_url;
 					dp->unpackString(media_url, "MediaURL");
-					if (!mMedia)
-					{
-						retval |= MEDIA_URL_ADDED;
-						mMedia = new LLViewerObjectMedia;
-						mMedia->mMediaURL = media_url;
-						mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
-						mMedia->mPassedWhitelist = FALSE;
-					}
-					else if (mMedia->mMediaURL != media_url)
-					{
-						retval |= MEDIA_URL_UPDATED;
-						mMedia->mMediaURL = media_url;
-						mMedia->mPassedWhitelist = FALSE;
-					}
-				}
-				else if (mMedia)
-				{
-					retval |= MEDIA_URL_REMOVED;
-					delete mMedia;
-					mMedia = NULL;
 				}
+                retval |= checkMediaURL(media_url);
 
 				//
 				// Unpack particle system data
@@ -3472,7 +3466,7 @@ U8 LLViewerObject::getMediaType() const
 	}
 	else
 	{
-		return LLViewerObject::MEDIA_TYPE_NONE;
+		return LLViewerObject::MEDIA_NONE;
 	}
 }
 
@@ -3734,16 +3728,13 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
 }
 
 
-void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) 
+void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) 
 {
-	U32 end = getNumTEs() ;
-	for (U32 face = 0 ; face < end ; face++)
+	if(index < 0 || index >= getNumTEs())
 	{
-		if(old_image == mTEImages[face])
-		{
-			mTEImages[face] = new_image ;
-		}
+		return ;
 	}
+	mTEImages[index] = new_image ;
 }
 
 S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 08e2ec47cd97e55befb6f57e5d13983b9cd01c16..bec36f9da7c5998e30f651efda257c1191e6ce99 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -158,10 +158,16 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	virtual BOOL	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
 
 	// Types of media we can associate
-	enum { MEDIA_TYPE_NONE = 0, MEDIA_TYPE_WEB_PAGE = 1 };
+	enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
 
 	// Return codes for processUpdateMessage
-	enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4, INVALID_UPDATE = 0x80000000 };
+	enum { 
+        MEDIA_URL_REMOVED = 0x1, 
+        MEDIA_URL_ADDED = 0x2, 
+        MEDIA_URL_UPDATED = 0x4, 
+        MEDIA_FLAGS_CHANGED = 0x8,
+        INVALID_UPDATE = 0x80000000
+    };
 
 	virtual U32		processUpdateMessage(LLMessageSystem *mesgsys,
 										void **user_data,
@@ -318,7 +324,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow);
 	/*virtual*/	BOOL	setMaterial(const U8 material);
 	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
-	void                changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image)  ;
+	void                changeTEImage(S32 index, LLViewerTexture* new_image)  ;
 	LLViewerTexture		*getTEImage(const U8 te) const;
 	
 	void fitFaceTexture(const U8 face);
@@ -504,6 +510,10 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	ExtraParameter* getExtraParameterEntry(U16 param_type) const;
 	ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
 	bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
+
+    // This function checks to see if the given media URL has changed its version
+    // and the update wasn't due to this agent's last action.
+    U32 checkMediaURL(const std::string &media_url);
 	
 public:
 	//
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 86d51bfd4b99488b21704992dfc186638d06da3d..a3f9c839a0dff6be3b54ac2df0e5413bc8c11011 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -46,6 +46,7 @@
 #include "llnotifications.h"
 #include "llfirstuse.h"
 #include "llpluginclassmedia.h"
+#include "llviewertexture.h"
 
 // Static Variables
 
@@ -219,17 +220,25 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
 			// Delete the old one first so they don't fight over the texture.
 			sMediaImpl->stop();
 
-			sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
-				media_width, media_height, media_auto_scale,
+			sMediaImpl = LLViewerMedia::newMediaImpl(
+				placeholder_texture_id,
+				media_width, 
+				media_height, 
+				media_auto_scale,
 				media_loop);
+			sMediaImpl->navigateTo(media_url);
 		}
 	}
 	else
 	{
 		// There is no media impl, make a new one
-		sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
-			media_width, media_height, media_auto_scale,
+		sMediaImpl = LLViewerMedia::newMediaImpl(
+			placeholder_texture_id,
+			media_width, 
+			media_height, 
+			media_auto_scale,
 			media_loop);
+		sMediaImpl->navigateTo(media_url);
 	}
 
 	LLFirstUse::useMedia();
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index c5b09403cb7df6c40889e87d8bd1ddb08b36fe2d..7ca11d83642c0a41fd87ab380fb9ffdf1ddbba53 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -50,7 +50,6 @@
 #include "llfirstuse.h"
 #include "llfloaterbuyland.h"
 #include "llfloatergroups.h"
-//#include "llfloaterhtml.h"
 #include "llfloatersellland.h"
 #include "llfloatertools.h"
 #include "llnotify.h"
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2c68a106c3768c804f8962adbd3ca697d5850b94..7ea55b49e869452ab988e4372a88eec4e8ead0f5 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1428,6 +1428,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("EventQueueGet");
 	capabilityNames.append("FetchInventory");
 	capabilityNames.append("WebFetchInventoryDescendents");
+	capabilityNames.append("ObjectMedia");
+	capabilityNames.append("ObjectMediaNavigate");
 	capabilityNames.append("FetchLib");
 	capabilityNames.append("FetchLibDescendents");
 	capabilityNames.append("GroupProposalBallot");
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e3d657068f4a9949b914beb9192ece3557c75a26..a2f6b70006a4975819c3f2ffad79df112817b8b9 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -62,6 +62,10 @@
 #include "llappviewer.h"
 #include "lltextureatlas.h"
 #include "lltextureatlasmanager.h"
+#include "lltextureentry.h"
+#include "llmediaentry.h"
+#include "llvovolume.h"
+#include "llviewermedia.h"
 ///////////////////////////////////////////////////////////////////////////////
 
 // statics
@@ -114,45 +118,18 @@ LLViewerTexture*  LLViewerTextureManager::findTexture(const LLUUID& id)
 		
 LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
 {
-	LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id);
-	if(iter == LLViewerMediaTexture::sMediaMap.end())
-		return NULL;
-
-	((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ;
-	return iter->second;
+	return LLViewerMediaTexture::findMediaTexture(media_id) ;	
 }
 
 LLViewerMediaTexture*  LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) 
 {
-	LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ;
+	LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id) ;	
 	if(!tex)
 	{
 		tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
 	}
 
-	LLViewerTexture* old_tex = tex->getOldTexture() ;
-	if(!old_tex)
-	{
-		//if there is a fetched texture with the same id, replace it by this media texture
-		old_tex = gTextureList.findImage(id) ;
-		if(old_tex)
-		{
-			tex->setOldTexture(old_tex) ;
-		}
-	}
-
-	if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo"))
-	{
-		if(!tex->isPlaying())
-		{
-			if(old_tex)
-			{
-				old_tex->switchToTexture(tex) ;
-			}
-			tex->setPlaying(TRUE) ;
-		}
-	}
-	tex->getLastReferencedTimer()->reset() ;
+	tex->initVirtualSize() ;
 
 	return tex ;
 }
@@ -303,7 +280,7 @@ void LLViewerTextureManager::cleanup()
 	LLViewerFetchedTexture::sMissingAssetImagep = NULL;
 	LLViewerFetchedTexture::sWhiteImagep = NULL;
 
-	LLViewerMediaTexture::sMediaMap.clear() ;
+	LLViewerMediaTexture::cleanup() ;	
 }
 
 //----------------------------------------------------------------------------------------------
@@ -437,6 +414,7 @@ void LLViewerTexture::init(bool firstinit)
 	mTextureState = NO_DELETE ;
 	mDontDiscard = FALSE;
 	mMaxVirtualSize = 0.f;
+	mNeedsResetMaxVirtualSize = FALSE ;
 }
 
 //virtual 
@@ -538,33 +516,24 @@ void LLViewerTexture::resetTextureStats(BOOL zero)
 	}
 }
 
+//virtual 
+F32 LLViewerTexture::getMaxVirtualSize()
+{
+	return mMaxVirtualSize ;
+}
+
+//virtual
 void LLViewerTexture::addFace(LLFace* facep) 
 {
 	mFaceList.push_back(facep) ;
 }
+
+//virtual
 void LLViewerTexture::removeFace(LLFace* facep) 
 {
 	mFaceList.remove(facep) ;
 }
 
-void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture)
-{
-	if(this == new_texture)
-	{
-		return ;
-	}
-
-	new_texture->addTextureStats(getMaxVirtualSize()) ;
-
-	for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); )
-	{
-		LLFace* facep = *iter++ ;
-		facep->setTexture(new_texture) ;
-		facep->getViewerObject()->changeTEImage(this, new_texture) ;
-		gPipeline.markTextured(facep->getDrawable());
-	}
-}
-
 void LLViewerTexture::forceActive()
 {
 	mTextureState = ACTIVE ; 
@@ -613,7 +582,16 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
 {
 	llassert_always(mGLTexturep.notNull()) ;	
 
-	return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
+	BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
+	
+	if(ret)
+	{
+		mFullWidth = mGLTexturep->getCurrentWidth() ;
+		mFullHeight = mGLTexturep->getCurrentHeight() ; 
+		mComponents = mGLTexturep->getComponents() ;
+	}
+
+	return ret ;
 }
 
 void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
@@ -2142,18 +2120,59 @@ void LLViewerMediaTexture::updateClass()
 
 	for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
 	{
-		LLViewerMediaTexture* mediap = iter->second;
-		++iter ;
+		LLViewerMediaTexture* mediap = iter->second;	
 
+		//
+		//Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
+		//
 		if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap
 		{
-			sMediaMap.erase(mediap->getID()) ;
+			media_map_t::iterator cur = iter++ ;
+			sMediaMap.erase(cur) ;
 		}
+		else
+		{
+			++iter ;
+		}
+	}
+}
+
+//static 
+void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id) 
+{
+	LLViewerMediaTexture* media_tex = findMediaTexture(media_id) ;
+	if(media_tex)
+	{
+		media_tex->invalidateMediaImpl() ;
 	}
 }
 
+//static
+void LLViewerMediaTexture::cleanup()
+{
+	sMediaMap.clear() ;
+}
+
+//static
+LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
+{
+	media_map_t::iterator iter = sMediaMap.find(media_id);
+	if(iter == sMediaMap.end())
+	{
+		return NULL;
+	}
+
+	LLViewerMediaTexture* media_tex = iter->second ;
+	media_tex->setMediaImpl() ;
+	media_tex->getLastReferencedTimer()->reset() ;
+
+	return media_tex;
+}
+
 LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) 
-	: LLViewerTexture(id, usemipmaps)	
+	: LLViewerTexture(id, usemipmaps),
+	mMediaImplp(NULL),
+	mUpdateVirtualSizeTime(0)
 {
 	sMediaMap.insert(std::make_pair(id, this));
 
@@ -2165,6 +2184,13 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
 	mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
 
 	mIsPlaying = FALSE ;
+
+	setMediaImpl() ;
+}
+
+//virtual 
+LLViewerMediaTexture::~LLViewerMediaTexture() 
+{	
 }
 
 void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
@@ -2172,7 +2198,6 @@ void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
 	mGLTexturep = NULL ;
 	init(false);
 	mUseMipMaps = usemipmaps ;
-	mIsPlaying = FALSE ;
 	getLastReferencedTimer()->reset() ;
 
 	generateGLTexture() ;
@@ -2195,14 +2220,336 @@ S8 LLViewerMediaTexture::getType() const
 	return LLViewerTexture::MEDIA_TEXTURE ;
 }
 
-void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex) 
+void LLViewerMediaTexture::invalidateMediaImpl() 
 {
-	mOldTexturep = tex ;
+	mMediaImplp = NULL ;
 }
+
+void LLViewerMediaTexture::setMediaImpl()
+{
+	if(!mMediaImplp)
+	{
+		mMediaImplp = LLViewerMedia::getMediaImplFromTextureID(mID) ;
+	}
+}
+
+//return true if all faces to reference to this media texture are found
+//Note: mMediaFaceList is valid only for the current instant 
+//      because it does not check the face validity after the current frame.
+BOOL LLViewerMediaTexture::findFaces()
+{	
+	mMediaFaceList.clear() ;
+
+	BOOL ret = TRUE ;
+
+	//for parcel media
+	LLViewerTexture* tex = gTextureList.findImage(mID) ;	
+	if(tex)
+	{
+		const ll_face_list_t* face_list = tex->getFaceList() ;
+		for(ll_face_list_t::const_iterator iter = face_list->begin(); iter != face_list->end(); ++iter)
+		{
+			mMediaFaceList.push_back(*iter) ;
+		}
+	}
 	
-LLViewerTexture* LLViewerMediaTexture::getOldTexture() const 
+	if(!mMediaImplp)
+	{
+		return TRUE ; 
+	}
+
+	//for media on a face.
+	const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList() ;
+	std::list< LLVOVolume* >::const_iterator iter = obj_list->begin() ;
+	for(; iter != obj_list->end(); ++iter)
+	{
+		LLVOVolume* obj = *iter ;
+		if(obj->mDrawable.isNull())
+		{
+			ret = FALSE ;
+			continue ;
+		}
+
+		S32 face_id = -1 ;
+		while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1)
+		{
+			LLFace* facep = obj->mDrawable->getFace(face_id) ;
+			if(facep)
+			{
+				mMediaFaceList.push_back(facep) ;
+			}
+			else
+			{
+				ret = FALSE ;
+			}
+		}
+	}
+
+	return ret ;
+}
+
+void LLViewerMediaTexture::initVirtualSize()
+{
+	if(mIsPlaying)
+	{
+		return ;
+	}
+
+	findFaces() ;
+	for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+	{
+		addTextureStats((*iter)->getVirtualSize()) ;
+	}
+}
+
+void LLViewerMediaTexture::addMediaToFace(LLFace* facep) 
+{
+	if(!mIsPlaying)
+	{
+		return ; //no need to add the face because the media is not in playing.
+	}
+
+	switchTexture(facep) ;
+}
+	
+void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep) 
+{
+	if(!mIsPlaying)
+	{
+		return ; //no need to remove the face because the media is not in playing.
+	}
+	if(!facep)
+	{
+		return ;
+	}
+
+	mIsPlaying = FALSE ; //set to remove the media from the face.
+	switchTexture(facep) ;
+	mIsPlaying = TRUE ; //set the flag back.
+
+	if(mFaceList.empty()) //no face referencing to this media
+	{
+		stopPlaying() ;
+	}
+}
+
+//virtual 
+void LLViewerMediaTexture::addFace(LLFace* facep) 
+{
+	LLViewerTexture::addFace(facep) ;
+
+	const LLTextureEntry* te = facep->getTextureEntry() ;
+	if(te)
+	{
+		LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+		if(tex)
+		{
+			mTextureList.push_back(tex) ;//increase the reference number by one for tex to avoid deleting it.
+			return ;
+		}
+	}
+	llerrs << "The face does not have a valid texture before media texture." << llendl ;
+}
+
+//virtual 
+void LLViewerMediaTexture::removeFace(LLFace* facep) 
+{
+	LLViewerTexture::removeFace(facep) ;
+
+	const LLTextureEntry* te = facep->getTextureEntry() ;
+	if(te)
+	{
+		LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+		if(tex)
+		{
+			for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+				iter != mTextureList.end(); ++iter)
+			{
+				if(*iter == tex)
+				{
+					mTextureList.erase(iter) ; //decrease the reference number for tex by one.
+					return ;
+				}
+			}
+
+			//
+			//we have some trouble here: the texture of the face is changed.
+			//we need to find the former texture, and remove it from the list to avoid memory leaking.
+			if(mFaceList.empty())
+			{
+				mTextureList.clear() ;
+				return ;
+			}
+			S32 end = mFaceList.size() ;
+			std::vector<const LLTextureEntry*> te_list(end) ;
+			S32 i = 0 ;			
+			for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+			{
+				te_list[i++] = (*iter)->getTextureEntry() ;//all textures are in use.
+			}
+			for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+				iter != mTextureList.end(); ++iter)
+			{
+				for(i = 0 ; i < end ; i++)
+				{
+					if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
+					{
+						te_list[i] = NULL ;
+						break ;
+					}
+				}
+				if(i == end) //no hit for this texture, remove it.
+				{
+					mTextureList.erase(iter) ; //decrease the reference number for tex by one.
+					return ;
+				}
+			}
+		}
+	}
+	llerrs << "mTextureList texture reference number is corrupted." << llendl ;
+}
+
+void LLViewerMediaTexture::stopPlaying()
+{
+	if(mMediaImplp)
+	{
+		mMediaImplp->stop() ;
+	}
+	mIsPlaying = FALSE ;			
+}
+
+void LLViewerMediaTexture::switchTexture(LLFace* facep)
+{
+	if(facep)
+	{
+		//check if another media is playing on this face.
+		if(facep->getTexture() && facep->getTexture() != this 
+			&& facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
+		{
+			if(mID == facep->getTexture()->getID()) //this is a parcel media
+			{
+				return ; //let the prim media win.
+			}
+		}
+
+		if(mIsPlaying) //old textures switch to the media texture
+		{
+			facep->switchTexture(this) ;
+		}
+		else //switch to old textures.
+		{
+			const LLTextureEntry* te = facep->getTextureEntry() ;
+			if(te)
+			{
+				LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
+				facep->switchTexture(tex) ;
+			}
+		}
+	}
+}
+
+void LLViewerMediaTexture::setPlaying(BOOL playing) 
 {
-	return mOldTexturep ;
+	if(!mMediaImplp)
+	{
+		return ; 
+	}
+	if(!playing && !mIsPlaying)
+	{
+		return ; //media is already off
+	}
+
+	if(playing == mIsPlaying && !mMediaImplp->isUpdated())
+	{
+		return ; //nothing has changed since last time.
+	}	
+
+	mIsPlaying = playing ;
+	if(mIsPlaying) //is about to play this media
+	{
+		if(findFaces())
+		{
+			//about to update all faces.
+			mMediaImplp->setUpdated(FALSE) ;
+		}
+
+		if(mMediaFaceList.empty())//no face pointing to this media
+		{
+			stopPlaying() ;
+			return ;
+		}
+
+		for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+		{
+			switchTexture(*iter) ;
+		}
+	}
+	else //stop playing this media
+	{
+		if(mFaceList.empty())
+		{
+			return ;
+		}
+
+		ll_face_list_t::iterator cur ;
+		for(ll_face_list_t::iterator iter = mFaceList.begin(); iter!= mFaceList.end(); )
+		{
+			cur = iter++ ; 
+			switchTexture(*cur) ; //cur could be removed in this function.
+		}
+	}
+	return ;
+}
+
+//virtual 
+F32 LLViewerMediaTexture::getMaxVirtualSize() 
+{	
+	if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
+	{
+		return mMaxVirtualSize ;
+	}
+	mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount() ;
+
+	if(mNeedsResetMaxVirtualSize)
+	{
+		mMaxVirtualSize = 0.f ;//reset
+		mNeedsResetMaxVirtualSize = FALSE ;
+	}
+
+	if(mIsPlaying) //media is playing
+	{
+		if(mFaceList.size() > 0) 
+		{				
+			for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+			{
+				LLFace* facep = *iter ;
+				if(facep->getDrawable()->isRecentlyVisible())
+				{
+					addTextureStats(facep->getVirtualSize()) ;
+				}
+			}	
+		}
+	}
+	else //media is not in playing
+	{
+		findFaces() ;
+	
+		if(!mMediaFaceList.empty())
+		{
+			for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+			{
+				LLFace* facep = *iter ;
+				if(facep->getDrawable()->isRecentlyVisible())
+				{
+					addTextureStats(facep->getVirtualSize()) ;
+				}
+			}
+		}
+	}
+
+	mNeedsResetMaxVirtualSize = TRUE ;
+
+	return mMaxVirtualSize ;
 }
 //----------------------------------------------------------------------------------------------
 //end of LLViewerMediaTexture
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 0be1bf81de3d81de1dc27cf3fb3a173c222d6cf6..596bfea670b33b91fa42b5dfdc31dc9c259e009f 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -49,6 +49,7 @@
 
 class LLFace;
 class LLImageGL ;
+class LLViewerObject;
 class LLViewerTexture;
 class LLViewerFetchedTexture ;
 class LLViewerMediaTexture ;
@@ -58,7 +59,9 @@ typedef	void	(*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_
 
 class LLVFile;
 class LLMessageSystem;
- 
+class LLViewerMediaImpl ;
+class LLVOVolume ;
+
 class LLLoadedCallbackEntry
 {
 public:
@@ -123,6 +126,8 @@ class LLViewerTexture : public LLTexture
 		BOOST_MAX_LEVEL
 	};
 	
+	typedef std::list<LLFace*> ll_face_list_t ;
+
 protected:
 	virtual ~LLViewerTexture();
 	LOG_CLASS(LLViewerTexture);
@@ -152,16 +157,17 @@ class LLViewerTexture : public LLTexture
 	//maxVirtualSize of the texture
 	void addTextureStats(F32 virtual_size) const ;
 	void resetTextureStats(BOOL zero = FALSE);
-	F32  getMaxVirtualSize()const {return mMaxVirtualSize ;} 
+	virtual F32  getMaxVirtualSize() ;
 
 	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
 	
 	S32 getFullWidth() const { return mFullWidth; }
 	S32 getFullHeight() const { return mFullHeight; }	
 
-	void addFace(LLFace* facep) ;
-	void removeFace(LLFace* facep) ; 
-	
+	virtual void addFace(LLFace* facep) ;
+	virtual void removeFace(LLFace* facep) ; 
+	const ll_face_list_t* getFaceList() const {return &mFaceList ;}
+
 	void generateGLTexture() ;
 	void destroyGLTexture() ;
 	
@@ -206,8 +212,6 @@ class LLViewerTexture : public LLTexture
 	//end of functions to access LLImageGL
 	//---------------------------------------------------------------------------------------------
 
-	void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture.
-
 	//-----------------
 	/*virtual*/ void setActive() ;
 	void forceActive() ;
@@ -233,10 +237,9 @@ class LLViewerTexture : public LLTexture
 	BOOL  mUseMipMaps ;
 	S8  mComponents;
 	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?
-
+	mutable BOOL mNeedsResetMaxVirtualSize ;
 	LLFrameTimer mLastReferencedTimer;
 
-	typedef std::list<LLFace*> ll_face_list_t ;
 	ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
 
 	//GL texture
@@ -498,34 +501,61 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
 class LLViewerMediaTexture : public LLViewerTexture
 {
 protected:
-	/*virtual*/ ~LLViewerMediaTexture() {}
+	/*virtual*/ ~LLViewerMediaTexture() ;
 
 public:
 	LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
 
 	/*virtual*/ S8 getType() const;
-
 	void reinit(BOOL usemipmaps = TRUE);	
 
 	BOOL  getUseMipMaps() {return mUseMipMaps ; }
-	void  setUseMipMaps(BOOL mipmap) ;
+	void  setUseMipMaps(BOOL mipmap) ;	
+	
+	void setPlaying(BOOL playing) ;
+	BOOL isPlaying() const {return mIsPlaying;}
+	void setMediaImpl() ;
 
-	void  setOldTexture(LLViewerTexture* tex) ;
-	LLViewerTexture* getOldTexture() const ;
+	void initVirtualSize() ;	
+	void invalidateMediaImpl() ;
 
-	void setPlaying(BOOL playing) {mIsPlaying = playing ;}
-	BOOL isPlaying() const {return mIsPlaying;}
+	void addMediaToFace(LLFace* facep) ;
+	void removeMediaFromFace(LLFace* facep) ;
+
+	/*virtual*/ void addFace(LLFace* facep) ;
+	/*virtual*/ void removeFace(LLFace* facep) ; 
+
+	/*virtual*/ F32  getMaxVirtualSize() ;
+private:
+	void switchTexture(LLFace* facep) ;
+	BOOL findFaces() ;
+	void stopPlaying() ;
 
 private:
-	LLPointer<LLViewerTexture> mOldTexturep ; //the texture this media texture replaces.
+	//
+	//an instant list, recording all faces referencing or can reference to this media texture.
+	//NOTE: it is NOT thread safe. 
+	//
+	std::list< LLFace* > mMediaFaceList ; 
+
+	//an instant list keeping all textures which are replaced by the current media texture,
+	//is only used to avoid the removal of those textures from memory.
+	std::list< LLPointer<LLViewerTexture> > mTextureList ;
+
+	LLViewerMediaImpl* mMediaImplp ;	
 	BOOL mIsPlaying ;
+	U32  mUpdateVirtualSizeTime ;
 
 public:
 	static void updateClass() ;
+	static void cleanup() ;	
 
-public:
+	static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
+	static void removeMediaImplFromTexture(const LLUUID& media_id) ;
+
+private:
 	typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
-	static media_map_t sMediaMap ;
+	static media_map_t sMediaMap ;	
 };
 
 //just an interface class, do not create instance from this class.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d23f10f8801102fec4eb7c09a538cbaac76d43aa..4a0efbaddc24716e2acca5426c626fbf89ff713d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3223,9 +3223,9 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans
 	// assume that pickAsync put the results in the back of the mPicks list
 	if(mPicks.size() != 0)
 	{
-	mLastPick = mPicks.back();
-	mLastPick.fetchResults();
-	mPicks.pop_back();
+		mLastPick = mPicks.back();
+		mLastPick.fetchResults();
+		mPicks.pop_back();
 	}
 	else
 	{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 93cb0f0f45562ba856307f9dc784704b5ef1770e..e69779b2dcc65302a39002bd97cda02b59740f7c 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -46,6 +46,8 @@
 #include "llvolumemessage.h"
 #include "material_codes.h"
 #include "message.h"
+#include "llmediadataresponder.h"
+#include "llpluginclassmedia.h" // for code in the mediaEvent handler
 #include "object_flags.h"
 #include "llagentconstants.h"
 #include "lldrawable.h"
@@ -65,6 +67,10 @@
 #include "llworld.h"
 #include "llselectmgr.h"
 #include "pipeline.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
+#include "llmediadatafetcher.h"
+#include "llagent.h"
 
 const S32 MIN_QUIET_FRAMES_COALESCE = 30;
 const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@@ -100,6 +106,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
 	mLODChanged = FALSE;
 	mSculptChanged = FALSE;
 	mSpotLightPriority = 0.f;
+
+	mMediaImplList.resize(getNumTEs());
 }
 
 LLVOVolume::~LLVOVolume()
@@ -108,14 +116,31 @@ LLVOVolume::~LLVOVolume()
 	mTextureAnimp = NULL;
 	delete mVolumeImpl;
 	mVolumeImpl = NULL;
+
+	if(!mMediaImplList.empty())
+	{
+		for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
+		{
+			if(mMediaImplList[i].notNull())
+			{
+				mMediaImplList[i]->removeObject(this) ;
+			}
+		}
+	}
 }
 
 
 // static
 void LLVOVolume::initClass()
 {
+	LLMediaDataFetcher::initClass();
 }
 
+// static
+void LLVOVolume::cleanupClass()
+{
+	LLMediaDataFetcher::cleanupClass();
+}
 
 U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 										  void **user_data,
@@ -123,6 +148,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 										  LLDataPacker *dp)
 {
 	LLColor4U color;
+	const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
 
 	// Do base class updates...
 	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -190,10 +216,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 		//
 		// Unpack texture entry data
 		//
-		if (unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+		if (result & teDirtyBits)
 		{
 			updateTEData();
 		}
+		if (result & TEM_CHANGE_MEDIA)
+		{
+			retval |= MEDIA_FLAGS_CHANGED;
+		}
 	}
 	else
 	{
@@ -226,9 +257,16 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 // 				llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
 				llwarns << "Bogus TE data in " << getID() << llendl;
 			}
-			else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+			else 
 			{
-				updateTEData();
+				if (res2 & teDirtyBits) 
+				{
+					updateTEData();
+				}
+				if (res2 & TEM_CHANGE_MEDIA)
+				{
+					retval |= MEDIA_FLAGS_CHANGED;
+				}
 			}
 
 			U32 value = dp->getPassFlags();
@@ -266,14 +304,29 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 				U8							tdpbuffer[1024];
 				LLDataPackerBinaryBuffer	tdp(tdpbuffer, 1024);
 				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num);
-				if ( unpackTEMessage(tdp) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
+				S32 result = unpackTEMessage(tdp);
+				if (result & teDirtyBits)
 				{
 					updateTEData();
 				}
+				if (result & TEM_CHANGE_MEDIA)
+				{
+					retval |= MEDIA_FLAGS_CHANGED;
+				}
 			}
 		}
 	}
-	
+	if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) {
+		// If the media changed at all, request new media data
+		if(mMedia)
+		{
+			llinfos << "Media URL: " << mMedia->mMediaURL << llendl;
+		}
+		requestMediaDataUpdate();
+	}
+	// ...and clean up any media impls
+	cleanUpMediaImpls();
+
 	return retval;
 }
 
@@ -1327,6 +1380,46 @@ BOOL LLVOVolume::isRootEdit() const
 	return TRUE;
 }
 
+//virtual
+void LLVOVolume::setNumTEs(const U8 num_tes)
+{
+	const U8 old_num_tes = getNumTEs() ;
+	
+	if(old_num_tes && old_num_tes < num_tes) //new faces added
+	{
+		LLViewerObject::setNumTEs(num_tes) ;
+
+		if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
+		{
+			mMediaImplList.resize(num_tes) ;
+			const LLTextureEntry* te = getTE(old_num_tes - 1) ;
+			for(U8 i = old_num_tes; i < num_tes ; i++)
+			{
+				setTE(i, *te) ;
+				mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
+			}
+			mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
+		}
+	}
+	else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
+	{
+		U8 end = mMediaImplList.size() ;
+		for(U8 i = num_tes; i < end ; i++)
+		{
+			removeMediaImpl(i) ;				
+		}
+		mMediaImplList.resize(num_tes) ;
+
+		LLViewerObject::setNumTEs(num_tes) ;
+	}
+	else
+	{
+		LLViewerObject::setNumTEs(num_tes) ;
+	}
+
+	return ;
+}
+
 void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
 {
 	BOOL changed = (mTEImages[te] != imagep);
@@ -1510,6 +1603,321 @@ void LLVOVolume::updateTEData()
 	}*/
 }
 
+bool LLVOVolume::hasMedia() const
+{
+	bool result = false;
+	const U8 numTEs = getNumTEs();
+	for (U8 i = 0; i < numTEs; i++)
+	{
+		const LLTextureEntry* te = getTE(i);
+		if(te->hasMedia())
+		{
+			result = true;
+			break;
+		}
+	}
+	return result;
+}
+
+void LLVOVolume::requestMediaDataUpdate()
+{
+	LLMediaDataFetcher::fetchMedia(this);
+}
+
+void LLVOVolume::cleanUpMediaImpls()
+{
+	// Iterate through our TEs and remove any Impls that are no longer used
+	const U8 numTEs = getNumTEs();
+	for (U8 i = 0; i < numTEs; i++)
+	{
+		const LLTextureEntry* te = getTE(i);
+		if( ! te->hasMedia())
+		{
+			// Delete the media IMPL!
+			removeMediaImpl(i) ;
+		}
+	}
+}
+
+void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array)
+{
+	// media_data_array is an array of media entry maps
+
+	//llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
+
+	LLSD::array_const_iterator iter = media_data_array.beginArray();
+	LLSD::array_const_iterator end = media_data_array.endArray();
+	U8 texture_index = 0;
+	for (; iter != end; ++iter, ++texture_index)
+	{
+		syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
+	}
+}
+
+void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
+{
+	LLTextureEntry *te = getTE(texture_index);
+	//llinfos << "BEFORE: texture_index = " << texture_index
+	//	<< " hasMedia = " << te->hasMedia() << " : " 
+	//	<< ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
+
+	std::string previous_url;
+	LLMediaEntry* mep = te->getMediaData();
+	if(mep)
+	{
+		// Save the "current url" from before the update so we can tell if
+		// it changes. 
+		previous_url = mep->getCurrentURL();
+	}
+
+	if (merge)
+	{
+		te->mergeIntoMediaData(media_data);
+	}
+	else {
+		// XXX Question: what if the media data is undefined LLSD, but the
+		// update we got above said that we have media flags??	Here we clobber
+		// that, assuming the data from the service is more up-to-date. 
+		te->updateMediaData(media_data);
+	}
+
+	mep = te->getMediaData();
+	if(mep)
+	{
+		bool update_from_self = false;
+		if (!ignore_agent) 
+		{
+			LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
+			update_from_self = (updating_agent == gAgent.getID());
+		}
+		viewer_media_t media_impl = LLViewerMedia::updateMediaImpl(mep, previous_url, update_from_self);
+			
+		addMediaImpl(media_impl, texture_index) ;
+	}
+
+	//llinfos << "AFTER: texture_index = " << texture_index
+	//	<< " hasMedia = " << te->hasMedia() << " : " 
+	//	<< ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
+}
+
+void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
+{
+	switch(event)
+	{
+		
+		case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
+		{			
+			switch(impl->getNavState())
+			{
+				case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
+				{
+					// This is the first location changed event after the start of a non-server-directed nav.  It may need to be broadcast.
+
+					bool block_navigation = false;
+					// FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
+					// to deal with multiple face indices.
+					int face_index = getFaceIndexWithMediaImpl(impl, -1);
+					std::string new_location = plugin->getLocation();
+					
+					// Find the media entry for this navigate
+					LLMediaEntry* mep = NULL;
+					LLTextureEntry *te = getTE(face_index);
+					if(te)
+					{
+						mep = te->getMediaData();
+					}
+					
+					if(mep)
+					{
+						if(!mep->checkCandidateUrl(new_location))
+						{
+							block_navigation = true;
+						}
+					}
+					else
+					{
+						llwarns << "Couldn't find media entry!" << llendl;
+					}
+										
+					if(block_navigation)
+					{
+						llinfos << "blocking navigate to URI " << new_location << llendl;
+
+						// "bounce back" to the current URL from the media entry
+						// NOTE: the only way block_navigation can be true is if we found the media entry, so we're guaranteed here that mep is not NULL.
+						impl->navigateTo(mep->getCurrentURL());
+					}
+					else
+					{
+						
+						llinfos << "broadcasting navigate with URI " << new_location << llendl;
+
+						// Post the navigate to the cap
+						std::string cap = getRegion()->getCapability("ObjectMediaNavigate");
+						if(cap.empty())
+						{
+							// XXX *TODO: deal with no cap!	 It may happen! (retry?)
+							LL_WARNS("Media") << "Can't broadcast navigate event -- ObjectMediaNavigate cap is not available" << LL_ENDL;
+							return;
+						}
+						
+						// If we got here, the cap is available.  Index through all faces that have this media and send the navigate message.
+						LLSD sd;
+						sd["object_id"] = mID;
+						sd["current_url"] = new_location;
+						sd["texture_index"] = face_index;
+						LLHTTPClient::post(cap, sd, new LLMediaDataResponder("ObjectMediaNavigate", sd, this));
+					}
+				}
+				break;
+				
+				case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
+					// This is the first location changed event after the start of a server-directed nav.  Don't broadcast it.
+					llinfos << "	NOT broadcasting navigate (server-directed)" << llendl;
+				break;
+				
+				default:
+					// This is a subsequent location-changed due to a redirect.	 Don't broadcast.
+					llinfos << "	NOT broadcasting navigate (redirect)" << llendl;
+				break;
+			}
+		}
+		break;
+		
+		default:
+		break;
+	}
+
+}
+
+void LLVOVolume::sendMediaDataUpdate() const
+{
+	std::string url = getRegion()->getCapability("ObjectMedia");
+	if (!url.empty())
+	{
+		LLSD sd_payload;
+		sd_payload["verb"] = "UPDATE";
+		sd_payload[LLTextureEntry::OBJECT_ID_KEY] = mID;
+		LLSD object_media_data;
+		for (int i=0; i < getNumTEs(); i++) {
+			LLTextureEntry *texture_entry = getTE(i);
+			llassert((texture_entry->getMediaData() != NULL) == texture_entry->hasMedia());
+			const LLSD &media_data =  
+				(texture_entry->getMediaData() == NULL) ? LLSD() : texture_entry->getMediaData()->asLLSD();
+			object_media_data.append(media_data);
+		}
+		sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data;
+
+		llinfos << "Sending media data: " << getID() << " " << ll_pretty_print_sd(sd_payload) << llendl;
+
+		LLHTTPClient::post(url, sd_payload, new LLMediaDataResponder("ObjectMedia", sd_payload, this));
+	}
+	// XXX *TODO: deal with no cap!	 It may happen! (retry?)
+}
+
+void LLVOVolume::removeMediaImpl(S32 texture_index)
+{
+	if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
+	{
+		return ;
+	}
+
+	//make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
+	if(mDrawable)
+	{
+		LLFace* facep = mDrawable->getFace(texture_index) ;
+		if(facep)
+		{
+			LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+			if(media_tex)
+			{
+				media_tex->removeMediaFromFace(facep) ;
+			}
+		}
+	}		
+	
+	//check if some other face(s) of this object reference(s)to this media impl.
+	S32 i ;
+	S32 end = (S32)mMediaImplList.size() ;
+	for(i = 0; i < end ; i++)
+	{
+		if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
+		{
+			break ;
+		}
+	}
+
+	if(i == end) //this object does not need this media impl.
+	{
+		mMediaImplList[texture_index]->removeObject(this) ;
+	}
+
+	mMediaImplList[texture_index] = NULL ;
+	return ;
+}
+
+void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
+{
+	if((S32)mMediaImplList.size() < texture_index + 1)
+	{
+		mMediaImplList.resize(texture_index + 1) ;
+	}
+	
+	if(mMediaImplList[texture_index].notNull())
+	{
+		if(mMediaImplList[texture_index] == media_impl)
+		{
+			return ;
+		}
+
+		removeMediaImpl(texture_index) ;
+	}
+
+	mMediaImplList[texture_index] = media_impl;
+	media_impl->addObject(this) ;	
+
+	//add the face to show the media if it is in playing
+	if(mDrawable)
+	{
+		LLFace* facep = mDrawable->getFace(texture_index) ;
+		if(facep)
+		{
+			LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+			if(media_tex)
+			{
+				media_tex->addMediaToFace(facep) ;
+			}
+		}
+		else //the face is not available now, start media on this face later.
+		{
+			media_impl->setUpdated(TRUE) ;
+		}
+	}
+	return ;
+}
+
+viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
+{
+	if(mMediaImplList.size() > face_id)
+	{
+		return mMediaImplList[face_id];
+	}
+	return NULL;
+}
+
+S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)
+{
+	S32 end = (S32)mMediaImplList.size() ;
+	for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
+	{
+		if(mMediaImplList[face_id] == media_impl)
+		{
+			return face_id ;
+		}
+	}
+	return -1 ;
+}
+
 //----------------------------------------------------------------------------
 
 void LLVOVolume::setLightTextureID(LLUUID id)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 1b90219836c5c439591dd57a04ed7a6844fbf52c..9a79b620d535b8d1ae878b26af56c4cc07c552f5 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -35,6 +35,7 @@
 
 #include "llviewerobject.h"
 #include "llviewertexture.h"
+#include "llviewermedia.h"
 #include "llframetimer.h"
 #include "llapr.h"
 #include "m3math.h"		// LLMatrix3
@@ -45,6 +46,8 @@ class LLViewerTextureAnim;
 class LLDrawPool;
 class LLSelectNode;
 
+typedef std::vector<viewer_media_t> media_list_t;
+
 enum LLVolumeInterfaceType
 {
 	INTERFACE_FLEXIBLE = 1,
@@ -75,12 +78,14 @@ class LLVolumeInterface
 // Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME)
 class LLVOVolume : public LLViewerObject
 {
+	LOG_CLASS(LLVOVolume);
 protected:
 	virtual				~LLVOVolume();
 
 public:
 	static		void	initClass();
-	static 		void 	preUpdateGeom();
+	static		void	cleanupClass();
+	static		void	preUpdateGeom();
 	
 	enum 
 	{
@@ -153,6 +158,7 @@ class LLVOVolume : public LLViewerObject
 
 	/*virtual*/ void	setScale(const LLVector3 &scale, BOOL damped);
 
+	/*virtual*/ void	setNumTEs(const U8 num_tes);
 	/*virtual*/ void	setTEImage(const U8 te, LLViewerTexture *imagep);
 	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);
 	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);
@@ -224,13 +230,31 @@ class LLVOVolume : public LLViewerObject
 	BOOL isVolumeGlobal() const;
 	BOOL canBeFlexible() const;
 	BOOL setIsFlexible(BOOL is_flexible);
-			
+
+	void updateObjectMediaData(const LLSD &media_data_duples);
+	void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
+
+	// Sync the given media data with the impl and the given te
+	void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
+	
+	// Send media data update to the simulator.
+	void sendMediaDataUpdate() const;
+
+	viewer_media_t getMediaImpl(U8 face_id) const;
+	S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id);
+   
+	bool hasMedia() const;
+
 protected:
 	S32	computeLODDetail(F32	distance, F32 radius);
 	BOOL calcLOD();
 	LLFace* addFace(S32 face_index);
 	void updateTEData();
 
+	void requestMediaDataUpdate();
+	void cleanUpMediaImpls();
+	void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
+	void removeMediaImpl(S32 texture_index) ;
 public:
 	LLViewerTextureAnim *mTextureAnimp;
 	U8 mTexAnimMode;
@@ -251,6 +275,7 @@ class LLVOVolume : public LLViewerObject
 	LLVolumeInterface *mVolumeImpl;
 	LLPointer<LLViewerFetchedTexture> mSculptTexture;
 	LLPointer<LLViewerFetchedTexture> mLightTexture;
+	media_list_t mMediaImplList;
 	
 	// statics
 public:
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index da1cd596192bf181f7be730d18075eb9e98292d4..7e22e17188e0e10b5248f5f40849415fd2849e05 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -94,7 +94,7 @@
      value="0.58 0.66 0.84 1" />
     <color
      name="AvatarNameColor"
-     value="0.98 0.69 0.36 1" />
+     reference="White" />
     <color
      name="BackgroundChatColor"
      reference="DkGray_66" />
@@ -253,7 +253,7 @@
      reference="White_10" />
     <color
      name="DefaultHighlightLight"
-	 reference="White_25" />
+     reference="White_25" />
     <color
      name="DefaultShadowDark"
      reference="Black_50" />
@@ -493,7 +493,7 @@
      value="0 0.78 0.78 1" />
     <color
      name="NotifyBoxColor"
-     value="0.27 0.67 1 1" />
+     value="LtGray" />
     <color
      name="NotifyCautionBoxColor"
      value="1 0.82 0.46 1" />
@@ -625,7 +625,7 @@
      reference="Black" />
     <color
      name="TextDefaultColor"
-     value="0 0 0 .33" />
+     value="Black" />
     <color
      name="TextEmbeddedItemColor"
      value="0 0 0.5 1" />
@@ -643,16 +643,16 @@
 	 value="0 0 0 .33" />
     <color
      name="TimeTextColor"
-     reference="LtGray" />
+     reference="LtGray_50" />
     <color
      name="TitleBarFocusColor"
      reference="White_10" />
     <color
      name="ToolTipBgColor"
-     value="0 0 0 .75" />
+     value="DkGray" />
     <color
      name="ToolTipBorderColor"
-     value="0 0 0 .75" />
+     value="White_50" />
     <color
      name="ToolTipTextColor"
      reference="LtGray" />
diff --git a/indra/newview/skins/default/html/en-us/help-offline/index.html b/indra/newview/skins/default/html/en-us/help-offline/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..bf3677603e1546a2158ff66cbd7ee39ebd6d0d62
--- /dev/null
+++ b/indra/newview/skins/default/html/en-us/help-offline/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Offline Help</title>
+<style>
+body {background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;width:100%;padding:0px;margin:0px;}
+a {color:#93a9d5;}
+a:active {color:#50607C;text-decoration:underline;}
+a:hover {color:#ff7900;text-decoration:underline;}
+#infobox{position:absolute;top:40%;left:50%;z-index:1;padding:0;width:592px;margin-left:-296px;margin-top:-150px;text-align:center;font-size:1.2em; color:#ccc;}
+#infobox #submitbtn {padding:15px 3px 5px 15px;height:28px;width:127px;margin-left:244px;}
+#infobox #submitbtn input {text-transform:capitalize;color:#fff;font-size:1.0em;height:28px;width:127px;border:none;font-weight:normal;background:url(../../btn_purplepill_bg.png) bottom left no-repeat;vertical-align:text-bottom;font-weight:bold;}
+#infobox #submitbtn input:hover.input_over, #login_box #submitbtn input:hover.input_off {color:#fff;border:none;background:url(../../btn_purplepill_bg.png) bottom right no-repeat;}
+#infobox #submitbtn input:active.input_over {color:#fff;border:none;background:url(../../btn_purplepill_bg.png) top left no-repeat;}
+#infobox #submitbtn input.pressed {color:#888;border:none;background:url(../../btn_purplepill_bg.png) top right no-repeat;}
+</style>
+</head>
+<body>
+<div id="infobox">
+		<p>
+			Second Life Offline Help.
+		</p>
+		<p>
+			You are not online and are configured not to fetch help remotely. This is all the help that is available
+			until more stuff is done. Yeah.
+		</p>
+	</div>
+</div>
+</body>
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 46c294768da14ca3821d8691ede48ac044219c2a..8a6e9486a291b4c29c96b44ca16c10756f79661c 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -110,12 +110,10 @@
   <texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false" />
   <texture name="Home_Press" file_name="navbar/Home_Press.png" preload="false" />
 
-  <texture name="Icon_Close_Background" file_name="windows/Icon_Close_Background.png" preload="true" />
   <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" />
   <texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" />
   <texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" />
 
-  <texture name="Icon_Dock_Background" file_name="windows/Icon_Dock_Background.png" preload="true" />
   <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" />
   <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" />
 
@@ -125,16 +123,16 @@
   <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" />
   <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" />
 
-  <texture name="Icon_Help_Background" file_name="windows/Icon_Help_Background.png" preload="false" />
   <texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="false" />
   <texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="false" />
   <texture name="Icon_Info" file_name="windows/Icon_Info.png" preload="false" />
 
-  <texture name="Icon_Minimize_Background" file_name="windows/Icon_Minimize_Background.png" preload="true" />
   <texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" />
   <texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" />
 
-  <texture name="Icon_Undock_Background" file_name="windows/Icon_Undock_Background.png" preload="false" />
+  <texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" />
+  <texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" />
+
   <texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="false" />
   <texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="false" />
 
@@ -175,6 +173,9 @@
   <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
   <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
 
+  <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
+  <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
+
   <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" />
   <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" />
 
@@ -442,8 +443,6 @@
   <texture name="cam_zoom_plus_in.tga" preload="false" />
   <texture name="cam_zoom_minus_in.tga" preload="false" />
 
-  <texture name="close_inactive_blue.tga" />
-  <texture name="closebox.tga" />
   <texture name="icn_clear_lineeditor.tga" />
 
   <texture name="icn_chatbar.tga" />
@@ -493,10 +492,6 @@
   <texture name="up_arrow.tga" file_name="up_arrow.png" />
   <texture name="down_arrow.tga" file_name="down_arrow.png" />
 
-  <texture name="restore_inactive.tga" />
-  <texture name="restore.tga" />
-  <texture name="restore_pressed.tga" />
-
   <texture name="tearoffbox.tga" />
   <texture name="tearoff_pressed.tga" />
 
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1f21e8194f946afd6e5b1bc838a88cee2f8ad0c
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png differ
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1d602f6f0c303ccb79c7a0e84cc5e3fe925cc28
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e753aaf1dd032b6d93001bbee2cf2f7b1977512
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
new file mode 100644
index 0000000000000000000000000000000000000000..be66b0523075b124a524502d0f051395515e802b
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png differ
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 97afe6d324dbca9ee5b58f90072ce6e694c18419..c9e143bf9503f80b9020f73d7510023ed8400f12 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -3,6 +3,7 @@
  height="440"
  layout="topleft"
  name="floater_about"
+ help_topic="floater_about"
  save_rect="true"
  title="About [APP_NAME]"
  width="470">
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 52c7944ba9f85762acfa119126d4517cdc41e183..991c9a84a3f09a4ab8121b11dd3b4343a419d9cd 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -1,296 +1,291 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <floater
  can_minimize="false"
- height="270"
+ height="275"
  layout="topleft"
  name="buy currency"
- help_topic="buy_currency"
+ help_topic="buy_linden_dollars"
  single_instance="true"
- title="Buy Currency"
+ title="Buy L$"
  width="350">
     <floater.string
      name="buy_currency">
-        Buy L$ [LINDENS] for approx. US$ [USD]
+        Buy L$ [LINDENS] for approx. [LOCALAMOUNT]
     </floater.string>
-    <text
+    <floater.string
+     name="account_website">
+        http://secondlife.com/account/billing.php
+    </floater.string>
+    <icon
+     height="215"
+     image_name="Linden_Dollar_Background"
+     layout="topleft"
+     left="0"
+     name="normal_background"
+     top="17"
+     width="350" />
+   <text
      type="string"
      length="1"
-     bottom_delta="48"
      follows="top|left"
      font="SansSerifHuge"
-     height="24"
      layout="topleft"
-     left="16"
-     name="info_buying"
-     right="-20">
-        Buying Currency:
+     left="20"
+     height="30"
+     top="30"
+     width="300"
+     name="info_need_more">
+        You need more L$:
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="0"
      follows="top|left"
-     font="SansSerifHuge"
-     height="24"
+     height="16"
      layout="topleft"
-     left="16"
-     name="info_cannot_buy"
-     right="-20">
-        Cannot buy now:
+     left="20"
+     width="300"
+     name="contacting">
+        Contacting LindeX...
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="0"
      follows="top|left"
      font="SansSerifHuge"
-     height="24"
      layout="topleft"
-     left="16"
-     name="info_need_more"
-     right="-20">
-        You need more currency:
+     left="20"
+     height="30"
+     top="30"
+     width="200"
+     name="info_buying">
+        Buy L$
     </text>
-    <icon
-     follows="top|left"
-     height="64"
-     image_name="badge_note.j2c"
-     layout="topleft"
-     left="0"
-     name="step_error"
-     top="48"
-     width="64" />
     <text
      type="string"
      length="1"
-     bottom_delta="96"
-     follows="top|left"
-     height="140"
-     layout="topleft"
-     left="72"
-     name="error_message"
-     right="-20">
-        Something ain&apos;t right.
-    </text>
-    <button
-     follows="bottom|left"
-     height="20"
-     label="Go to website"
-     layout="topleft"
-     left_delta="0"
-     name="error_web"
-     top_delta="124"
-     width="120" />
-    <icon
-     follows="top|left"
-     height="64"
-     image_name="badge_note.j2c"
-     layout="topleft"
-     left="0"
-     name="step_1"
-     top="48"
-     width="64" />
-    <text
-     type="string"
-     length="1"
-     bottom_delta="-38"
      follows="top|left"
+     font="SansSerifMedium"
      height="16"
      layout="topleft"
-     left="72"
-     name="contacting"
-     right="-20">
-        Contacting LindeX...
+     left="20"
+     name="balance_label"
+     top_pad="10"
+     width="210">
+        I have
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="0"
+     font="SansSerifMedium"
      follows="top|left"
+     halign="right"
      height="16"
      layout="topleft"
-     left="72"
-     name="buy_action_unknown"
-     right="-20">
-        Buy L$ on the LindeX currency exchange
+     left="200"
+     name="balance_amount"
+     top_delta="0"
+     width="100">
+        L$ [AMT]
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="0"
      follows="top|left"
+     font="SansSerifMedium"
      height="16"
+     top_pad="15"
      layout="topleft"
-     left="72"
-     name="buy_action"
-     right="-20">
-        [NAME] L$ [PRICE]
+     left="20"
+     name="currency_action"
+     width="210">
+        I want to buy
     </text>
     <text
+     font="SansSerifMedium"
      type="string"
      length="1"
-     follows="top|left"
+     follows="left|top"
      height="16"
      layout="topleft"
-     left_delta="0"
-     name="currency_action"
-     top_pad="4"
-     width="40">
-        Buy L$
+     top_delta="0"
+     left="222"
+     name="currency_label"
+     width="15">
+      L$
     </text>
     <line_editor
      type="string"
-     length="1"
-     follows="top|right"
-     height="16"
-     layout="topleft"
-     left_pad="5"
+     halign="right"
+     font="SansSerifMedium"
+     select_on_focus="true"
+     follows="top|left"
+     top_delta="-7"
+     height="22"
+     label="L$"
+     left_pad="3"
      name="currency_amt"
-     top_delta="0"
-     width="80">
+     width="60">
         1234
     </line_editor>
     <text
      type="string"
-     length="1"
-     follows="top|right"
-     height="16"
-     layout="topleft"
-     left_pad="5"
-     name="currency_est"
-     top_delta="0"
-     width="180">
-        for approx. US$ [USD,number,2]
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="top|right"
-     height="16"
-     layout="topleft"
-     left_delta="5"
-     name="getting_data"
-     top_delta="0"
-     width="180">
-        Getting data...
-    </text>
-    <text
-     type="string"
+     font="SansSerifMedium"
      length="1"
      follows="top|left"
      height="16"
      layout="topleft"
-     left="80"
-     name="balance_label"
-     top="110"
-     width="240">
-        You currently have
+     left="20"
+     top_pad="10"
+     name="buying_label"
+     width="210">
+        For the price
     </text>
     <text
      type="string"
      length="1"
+     font="SansSerifMedium"
+     text_color="EmphasisColor"
      follows="top|left"
      halign="right"
      height="16"
-     layout="topleft"
-     left_delta="0"
-     name="balance_amount"
      top_delta="0"
-     width="240">
-        L$ [AMT]
+     layout="topleft"
+     left="170"
+     name="currency_est"
+     width="130">
+     [LOCALAMOUNT]
     </text>
     <text
      type="string"
+     font="SansSerifSmall"
+     text_color="EmphasisColor"
      length="1"
      follows="top|left"
      height="16"
      layout="topleft"
-     left_delta="0"
-     name="buying_label"
-     top_pad="4"
-     width="240">
-        You are buying
+     left="40"
+     width="100"
+     halign="right"
+     name="getting_data">
+        Estimating...
     </text>
     <text
      type="string"
+     font="SansSerifSmall"
+     top_delta="0"
      length="1"
      follows="top|left"
      halign="right"
      height="16"
+     left_pad="10"
+     width="150"
      layout="topleft"
-     left_delta="0"
-     name="buying_amount"
-     top_delta="0"
-     width="240">
-        L$ [AMT]
+     name="buy_action">
+        [NAME] L$ [PRICE]
     </text>
     <text
      type="string"
+     font="SansSerifMedium"
      length="1"
      follows="top|left"
      height="16"
      layout="topleft"
-     left_delta="0"
+     left="20"
      name="total_label"
-     top_pad="4"
-     width="240">
-        Your balance will be
+     width="210">
+        My new balance will be
     </text>
     <text
      type="string"
      length="1"
+     font="SansSerifMedium"
      follows="top|left"
-     halign="right"
+     top_delta="0"
      height="16"
      layout="topleft"
-     left_delta="0"
+     left="200"
+     halign="right"
      name="total_amount"
-     top_delta="0"
-     width="240">
+     width="100">
         L$ [AMT]
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="48"
      follows="top|left"
-     height="32"
      layout="topleft"
-     left="72"
-     name="purchase_warning_repurchase"
-     right="-20">
-        Confirming this purchase only buys the currency.
-You&apos;ll need to try the operation again.
+     left="20"
+     width="300"
+     name="purchase_warning_repurchase">
+        Confirming this purchase only buys the L$.
+You&apos;ll need to try again.
     </text>
     <text
      type="string"
      length="1"
-     bottom_delta="0"
      follows="top|left"
-     height="32"
      layout="topleft"
-     left="72"
-     name="purchase_warning_notenough"
-     right="-20">
-        You aren&apos;t buying enough currency
+     left="20"
+     name="purchase_warning_notenough">
+        You aren&apos;t buying enough L$.
 Increase the amount to buy.
     </text>
+
+    <button
+     follows="bottom|left"
+     height="20"
+     label="Buy Now"
+     layout="topleft"
+     left="151"
+     name="buy_btn"
+     top="248"
+     width="90"/>
     <button
      follows="bottom|right"
      height="20"
      label="Cancel"
      layout="topleft"
-     left="237"
+     left_pad="10"
      name="cancel_btn"
-     top="234"
-     width="90" />
-    <button
-     follows="bottom|left"
-     height="20"
-     label="Purchase"
+     width="90"/>
+    <icon
+     height="215"
+     image_name="Linden_Dollar_Alert"
      layout="topleft"
-     left_delta="-96"
-     name="buy_btn"
-     top_delta="0"
-     width="90" />
+     left="0"
+     name="error_background"
+     top="15"
+     width="350"/>
+    <text
+     type="string"
+     font="SansSerifHuge"
+     left="170"
+     width="170"
+     height="80"
+     top="30"
+     name="info_cannot_buy">
+        Take your
+[SECOND_LIFE] to
+the next level...
+    </text>
+     <button
+      follows="bottom|left"
+      height="20"
+      label="Continue to the Web"
+      layout="topleft"
+      left="170"
+      name="error_web"
+      top="120"
+      width="160"/>
+     <text
+      type="string"
+      width="350"
+      height="20"
+      top_pad="92"
+      left_pad="-300"
+      follows="bottom|right"
+      name="cannot_buy_message">
+        Continue to the web site and enter payment information
+     </text>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml
index a1265d49f9747c657fa48736c226e7829d7357a1..512b4c85a1321c53933500c4c8c41de5a07068f1 100644
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  can_resize="true"
- height="440"
+ height="400"
  layout="topleft"
  min_height="140"
  min_width="467"
@@ -9,8 +9,8 @@
  help_topic="floater_help_browser"
  save_rect="true"
  single_instance="true"
- title="Holy Bananas, it's the Help Browser"
- width="820">
+ title="Help Browser"
+ width="620">
     <floater.string
      name="home_page_url">
         http://www.secondlife.com
@@ -20,150 +20,13 @@
         http://support.secondlife.com
     </floater.string>
     <layout_stack
-     bottom="440"
+     bottom="400"
      follows="left|right|top|bottom"
      layout="topleft"
      left="10"
      name="stack1"
      top="20"
-     width="800">
-        <layout_panel
-         auto_resize="false"
-         height="20"
-         layout="topleft"
-         left="0"
-         name="nav_controls"
-         top="400"
-         user_resize="false"
-         width="800">
-            <button
-             follows="left|top"
-             height="20"
-             label="Back"
-             layout="topleft"
-             left="0"
-             name="back"
-             top="0"
-             width="55" />
-            <button
-             follows="left|top"
-             height="20"
-             label="Forward"
-             layout="topleft"
-             left_pad="3"
-             name="forward"
-             top_delta="0"
-             width="68" />
-            <button
-             enabled="false"
-             follows="left|top"
-             height="20"
-             label="Reload"
-             layout="topleft"
-             left_pad="2"
-             name="reload"
-             top_delta="0"
-             width="70"/>
-            <combo_box
-             allow_text_entry="true"
-             follows="left|top|right"
-             height="20"
-             layout="topleft"
-             left_pad="5"
-             max_chars="255"
-             name="address"
-             top_delta="0"
-             width="540" />
-            <button
-             enabled="false"
-             follows="right|top"
-             height="20"
-             label="Go"
-             layout="topleft"
-             left_pad="5"
-             name="go"
-             top_delta="0"
-             width="55" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         height="20"
-         layout="topleft"
-         left_delta="0"
-         name="time_controls"
-         top_delta="0"
-         user_resize="false"
-         width="800">
-            <button
-             follows="left|top"
-             height="20"
-             label="rewind"
-             layout="topleft"
-             left="0"
-             name="rewind"
-             top="0"
-             width="55" />
-            <button
-             follows="left|top"
-             height="20"
-             image_selected="button_anim_play_selected.tga"
-             image_unselected="button_anim_play.tga"
-             layout="topleft"
-             left_delta="55"
-             name="play"
-             picture_style="true"
-             top_delta="0"
-             width="55" />
-            <button
-             follows="left|top"
-             height="20"
-             image_selected="button_anim_pause_selected.tga"
-             image_unselected="button_anim_pause.tga"
-             layout="topleft"
-             left_delta="0"
-             name="pause"
-             picture_style="true"
-             top_delta="0"
-             width="55" />
-            <button
-             follows="left|top"
-             height="20"
-             label="stop"
-             layout="topleft"
-             left_pad="10"
-             name="stop"
-             top_delta="0"
-             width="55" />
-            <button
-             follows="left|top"
-             height="20"
-             label="forward"
-             layout="topleft"
-             left_pad="20"
-             name="seek"
-             top_delta="0"
-             width="55" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         height="20"
-         layout="topleft"
-         left_delta="0"
-         name="parcel_owner_controls"
-         top_delta="0"
-         user_resize="false"
-         width="540">
-            <button
-             enabled="false"
-             follows="left|top"
-             height="20"
-             label="Send Current URL to Parcel"
-             layout="topleft"
-             left="0"
-             name="assign"
-             top="0"
-             width="200" />
-        </layout_panel>
+     width="600">
         <layout_panel
          height="20"
          layout="topleft"
@@ -171,7 +34,7 @@
          name="external_controls"
          top_delta="0"
          user_resize="false"
-         width="540">
+         width="570">
             <web_browser
              bottom="-10"
              follows="left|right|top|bottom"
@@ -179,7 +42,7 @@
              left="0"
              name="browser"
              top="0"
-             width="540" />
+             width="570" />
             <button
              follows="bottom|left"
              height="20"
@@ -189,25 +52,17 @@
              name="open_browser"
              top_pad="5"
              width="185" />
-            <check_box
-             control_name="UseExternalBrowser"
-             follows="bottom|left"
-             height="20"
-             label="Always open in my web browser"
-             layout="topleft"
-             left_pad="5"
-             name="open_always"
-             top_delta="0"
-             width="200" />
+<!--
             <button
              follows="bottom|right"
              height="20"
              label="Close"
              layout="topleft"
-             left_pad="80"
+             left_pad="290"
              name="close"
              top_delta="0"
              width="70" />
+-->
         </layout_panel>
     </layout_stack>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_media_settings.xml b/indra/newview/skins/default/xui/en/floater_media_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6ba26f938d9d501975c5f2c2be65a66e51642c76
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_media_settings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater bottom="-666" can_close="true" can_drag_on_left="false" can_minimize="true"
+     can_resize="false" can_tear_off="true" default_tab_group="1" enabled="true"
+      width="365" height="535" left="330" min_height="430" min_width="620"
+     mouse_opaque="true" name="Medis Settings" title="Media Settings">
+	<button bottom="-525" enabled="true" follows="right|bottom" font="SansSerif"
+	     halign="center" height="20" label="OK" label_selected="OK" left="75"
+	     mouse_opaque="true" name="OK" scale_image="true" width="90" />
+	<button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
+	     halign="center" height="20" label="Cancel" label_selected="Cancel"
+	     left_delta="93" mouse_opaque="true" name="Cancel" scale_image="true"
+	     width="90" />
+	<button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
+	     halign="center" height="20" label="Apply" label_selected="Apply"
+	     left_delta="93" mouse_opaque="true" name="Apply" scale_image="true"
+	     width="90" />
+	<tab_container bottom="-500" enabled="true" follows="left|top|right|bottom" height="485"
+	     left="0" mouse_opaque="false" name="tab_container" tab_group="1"
+	     tab_position="top" tab_width="80" width="365" />
+</floater>
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 30406cad63e1a470438422cd8fe9fe8007fcdf01..aef5707fd4efeeac34ee1710e61619362d14277f 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -12,7 +12,7 @@
  width="320"
  min_width="320"
  height="23"
- can_minimize="false"
+ can_minimize="true"
  can_tear_off="false"
  can_resize="false"
  can_drag_on_left="false"
@@ -22,10 +22,10 @@
     <flat_list_view
 	    color="FloaterDefaultBackgroundColor"
 	    follows="all"
-	layout="topleft"
-			name="notification_list"
-			left="1"
+	    layout="topleft"
+	    name="notification_list"
+	    left="1"
 	    top="20"
-			height="0"
-			width="318"/>
+	    height="0"
+	    width="318"/>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index edbd28cd2d14b710943c36b830c7fbe52ec42e22..053215f8ae338cea9b1c7af44bcdffaa22ea8943 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -74,7 +74,11 @@
      name="button focus"
      picture_style="true"
      tool_tip="Focus"
-     width="20" />
+     width="20">
+	  <button.commit_callback
+	     function="BuildTool.setTool"
+	     parameter="Focus" />
+	</button>
     <button
      follows="left|top"
      height="20"
@@ -87,7 +91,11 @@
      name="button move"
      picture_style="true"
      tool_tip="Move"
-     width="20" />
+     width="20">
+	  <button.commit_callback
+	     function="BuildTool.setTool"
+	     parameter="Move" />
+	</button>
     <button
      follows="left|top"
      height="20"
@@ -100,7 +108,11 @@
      name="button edit"
      picture_style="true"
      tool_tip="Edit"
-     width="20" />
+     width="20">
+	  <button.commit_callback
+	     function="BuildTool.setTool"
+	     parameter="Edit" />
+	</button>
     <button
      follows="left|top"
      height="20"
@@ -113,7 +125,11 @@
      name="button create"
      picture_style="true"
      tool_tip="Create"
-     width="20" />
+     width="20">
+	  <button.commit_callback
+	     function="BuildTool.setTool"
+	     parameter="Create" />
+	</button>
     <button
      follows="left|top"
      height="20"
@@ -126,7 +142,11 @@
      name="button land"
      picture_style="true"
      tool_tip="Land"
-     width="20" />
+     width="20">
+	  <button.commit_callback
+	     function="BuildTool.setTool"
+	     parameter="Land" />
+	</button>
     <text
      type="string"
      text_color="LabelSelectedDisabledColor"
@@ -160,6 +180,8 @@
          label="Pan (Ctrl-Shift)"
          layout="topleft"
          name="radio pan" />
+		 <radio_group.commit_callback
+	     function="BuildTool.commitRadioFocus"/>
     </radio_group>
    <slider_bar
      follows="left|top"
@@ -171,7 +193,10 @@
      top_delta="-2"
      left_delta="100"
      name="slider zoom"
-     width="134" />
+     width="134">
+	 <slider_bar.commit_callback
+	     function="BuildTool.commitZoom"/>
+	</slider_bar>
    <radio_group
       left="10"
       height="70"
@@ -193,6 +218,8 @@
          label="Spin (Ctrl-Shift)"
          layout="topleft"
          name="radio spin" />
+		 <radio_group.commit_callback
+	     function="BuildTool.commitRadioMove"/>
    </radio_group>
     <radio_group
      follows="left|top"
@@ -220,6 +247,8 @@
          label="Select Texture"
          layout="topleft"
          name="radio select face" />
+		  <radio_group.commit_callback
+	     function="BuildTool.commitRadioEdit"/>
     </radio_group>
     <check_box
       left="10"
@@ -227,7 +256,10 @@
       control_name="EditLinkedParts"
      label="Edit linked"
      layout="topleft"
-     name="checkbox edit linked parts" />
+     name="checkbox edit linked parts" >
+		  <check_box.commit_callback
+	     function="BuildTool.selectComponent"/>
+	</check_box>	 
     <combo_box
      height="19"
      left="10"
@@ -248,6 +280,8 @@
          label="Reference ruler"
          name="Reference"
          value="Reference" />
+		 <combo_box.commit_callback
+	     function="BuildTool.gridMode"/>
     </combo_box>
     <check_box
      control_name="ScaleUniform"
@@ -286,7 +320,10 @@
      name="Options..."
      tool_tip="Set the Grid Options"
      width="26"
-     height="22" />
+     height="22" >
+	 <button.commit_callback
+	     function="BuildTool.gridOptions"/>
+	</button>
     <button
      follows="left|top"
      height="20"
@@ -597,8 +634,9 @@
          name="radio revert"
          top_delta="15"
          width="114" />
+		 <radio_group.commit_callback
+	     function="BuildTool.commitRadioLand"/>
     </radio_group>
-
     <text
      type="string"
      length="1"
@@ -624,6 +662,7 @@
         Size
     </text>
     <slider_bar
+	 control_name ="LandBrushSize"
      follows="left|top"
      height="19"
      initial_value="2.0"
@@ -656,7 +695,10 @@
      min_val="-1"
      name="slider force"
      top_delta="-3"
-     width="80" />
+     width="80" >
+	  <slider_bar.commit_callback
+	     function="BuildTool.LandBrushForce"/>
+    </slider_bar>
     <button
      follows="left|top"
      font="SansSerifSmall"
@@ -668,7 +710,10 @@
      left="135"
      name="button apply to selection"
      tool_tip="Modify Selected Land"
-     width="78" />
+     width="78">
+	  <button.commit_callback
+	     function="BuildTool.applyToSelection"/>
+    </button>
     <text
      type="string"
      text_color="LabelSelectedDisabledColor"
@@ -2215,7 +2260,7 @@
              left="10"
              name="texture control"
              tool_tip="Click to choose a picture"
-             top="10"
+             top="8"
              width="64" />
             <color_swatch
              border_color="0.45098 0.517647 0.607843 1"
@@ -2237,7 +2282,7 @@
              layout="topleft"
              left_pad="20"
              name="color trans"
-             top="10"
+             top="6"
              width="100">
                 Transparency %
             </text>
@@ -2261,7 +2306,7 @@
              layout="topleft"
              left_delta="0"
              name="glow label"
-             top_pad="4"
+             top_pad="2"
              width="80">
                 Glow
             </text>
@@ -2281,7 +2326,7 @@
              layout="topleft"
              left_delta="0"
              name="checkbox fullbright"
-             top_pad="7"
+             top_pad="4"
              width="81" />
             <text
              type="string"
@@ -2291,7 +2336,7 @@
              layout="topleft"
              left="10"
              name="tex gen"
-             top_pad="10"
+             top_pad="5"
              width="87">
                 Mapping
             </text>
@@ -2439,6 +2484,40 @@
                  name="weave"
                  value="weave" />
             </combo_box>
+          <!--          
+            <line_editor
+             bevel_style="in"
+             border_style="line"
+             border_thickness="1"
+             follows="left|top"
+             height="16"
+             layout="topleft"
+             left="10"
+             max_length="63"
+             name="Home Url"
+             select_on_focus="true"
+             top="134"
+             width="250" />
+            <check_box
+             height="16"
+             label="Media Face"
+             layout="topleft"
+             left_delta="0"
+             name="has media"
+             top_pad="6"
+             width="70" />
+            <button
+             follows="left|top"
+             font="SansSerifSmall"
+             height="20"
+             label="Set Media Info"
+             label_selected="Set Media Info"
+             layout="topleft"
+             left_pad="60"
+             name="media info set"
+             top_delta="-4"
+             width="120" />
+-->             
             <text
              type="string"
              length="1"
@@ -2447,7 +2526,7 @@
              layout="topleft"
              left="10"
              name="tex scale"
-             top_pad="15"
+             top_pad="5"
              width="200">
                 Repeats per Face
             </text>
@@ -2461,7 +2540,7 @@
              left="20"
              max_val="100"
              name="TexScaleU"
-             top_pad="10"
+             top_pad="6"
              width="160" />
             <check_box
              height="19"
@@ -2469,7 +2548,7 @@
              layout="topleft"
              left_pad="10"
              name="checkbox flip s"
-             top_delta="1"
+             top_delta="0"
              width="70" />
             <spinner
              follows="left|top"
@@ -2489,61 +2568,43 @@
              layout="topleft"
              left_pad="10"
              name="checkbox flip t"
-             top_delta="1"
+             top_delta="0"
              width="70" />
-            <text
-             type="string"
-             length="1"
-             follows="left|top"
-             height="10"
-             layout="topleft"
-             left="10"
-             name="tex rotate"
-             top_pad="20"
-             width="102">
-                Rotation (degrees)
-            </text>
+  
             <spinner
              decimal_digits="2"
              follows="left|top"
              height="19"
              increment="1"
              initial_value="0"
+			 label="Rotation (degrees)"
              layout="topleft"
-             left_delta="102"
+			 label_width="100"
+             left="10"
              max_val="9999"
              min_val="-9999"
              name="TexRot"
-             top_delta="0"
-             width="68" />
-            <text
-             type="string"
-             length="1"
-             follows="left|top"
-             height="10"
-             layout="topleft"
-             left="10"
-             name="rpt"
-             top_pad="0"
-             width="160">
-                Repeats Per Meter
-            </text>
+             top_delta="25"
+             width="170" />
+
             <spinner
              decimal_digits="1"
              follows="left|top"
              height="19"
              initial_value="1"
+			 label="Repeats Per Meter"
              layout="topleft"
-             left_delta="102"
+			 label_width="100"
+             left="10"
              max_val="10"
              min_val="0.1"
              name="rptctrl"
-             top_delta="0"
-             width="68" />
+             top_delta="20"
+             width="170" />
             <button
              follows="left|top"
              font="SansSerifSmall"
-             height="22"
+             height="18"
              label="Apply"
              label_selected="Apply"
              layout="topleft"
@@ -2558,7 +2619,7 @@
              layout="topleft"
              left="10"
              name="tex offset"
-             top_pad="20"
+             top_delta="20"
              width="200">
                 Texture Offset
             </text>
@@ -2572,7 +2633,7 @@
              left="20"
              min_val="-1"
              name="TexOffsetU"
-             top_pad="10"
+             top_pad="5"
              width="160" />
             <spinner
              follows="left|top"
@@ -2584,10 +2645,9 @@
              left_delta="0"
              min_val="-1"
              name="TexOffsetV"
-             top_pad="2"
+             top_pad="1"
              width="160" />
-<!--TODO: KILL THIS-->
- <!--           <text
+            <text
              type="string"
              length="1"
              follows="left|top"
@@ -2595,7 +2655,7 @@
              layout="topleft"
              left="10"
              name="textbox autofix"
-             top="332"
+             top_pad="4"
              width="160">
                 Align media texture
 (must load first)
@@ -2607,10 +2667,75 @@
              label="Align"
              label_selected="Align"
              layout="topleft"
-             left="112"
+             left="122"
              name="button align"
-             top="340"
-             width="68" />-->
+             top_pad="-19"
+             width="68" />
+    		<text
+			 type="string"
+			 length="1"
+			 follows="left|top"
+			 height="12"
+			 layout="topleft"
+			 left="10"
+			 top_pad="0"
+			 name="media_tex"
+			 width="100">
+				Media:
+			</text> 
+			<line_editor
+             follows="left|top|right"
+             height="18"
+             layout="topleft"
+             left="20"
+             max_length="63"
+             name="media_info"
+             select_on_focus="true"
+             top_delta="12"
+             width="230" />
+            <button
+             follows="left|top"
+             font="SansSerifSmall"
+             height="13"
+			 width="13"
+			 image_unselected="add_btn.tga"
+			 label=""
+             layout="topleft"
+             left="20"
+             name="add_media"
+             top_pad="3">
+				<button.commit_callback
+				function="BuildTool.AddMedia"/>
+			</button>
+			<button
+             follows="left|top"
+             font="SansSerifSmall"
+             height="13"
+			 width="13"
+			 image_unselected="del_btn.tga"
+			 label=""
+             layout="topleft"
+             left_pad="10"
+             name="delete_media"
+             top_delta="0"
+             left_delta="10" >
+				<button.commit_callback
+				function="BuildTool.DeleteMedia"/>
+			</button>
+            <button
+             follows="left|top"
+             font="SansSerifSmall"
+             height="15"
+			 width="15"
+			 image_unselected="gear.tga"
+			 label=""
+             layout="topleft"
+			 name="edit_media"
+             top_delta="0"
+             left_delta="190">
+				<button.commit_callback
+				function="BuildTool.EditMedia"/>
+			</button> 
         </panel>
        <panel
          border="false"
@@ -2642,13 +2767,13 @@
              width="130" />
             <panel_inventory
              follows="left|top"
-             height="310"
+             height="210"
              layout="topleft"
              left="10"
              name="contents_inventory"
              top="50"
              width="260" />
-        </panel>
+			</panel>
         </tab_container>
  <panel
       follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0eb2c5e1be710b05874751cae06cbcecbee4816a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="108"
+ layout="topleft"
+ name="whitelist_entry"
+ width="390">
+
+  <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
+     left="10" name="media_label" top="20">
+        Enter a URL or URL pattern to add to the list of allowed domains
+    </text>
+
+  <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
+	     height="20" left="10" name="whitelist_entry"
+	     tool_tip="Enter a URL or URL pattern to White List"
+	     width="350" />
+
+  <button follows="top|left" height="20" font="SansSerifSmall" label="OK"
+     layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
+  
+  <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
+     layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9cba27b88c40563ca1e76909c4c9673d57c48e8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Teleport History Item Context Menu">
+    <menu_item_call
+     label="Teleport"
+     layout="topleft"
+     name="Teleport">
+        <menu_item_call.on_click
+         function="TeleportHistory.Teleport" />
+    </menu_item_call>
+    <menu_item_call
+     label="More Information"
+     layout="topleft"
+     name="More Information">
+        <menu_item_call.on_click
+         function="TeleportHistory.MoreInformation" />
+    </menu_item_call>
+    <menu_item_call
+     label="Copy"
+     layout="topleft"
+     name="Copy">
+        <menu_item_call.on_click
+         function="TeleportHistory.Copy" />
+    </menu_item_call>
+    <menu_item_call
+     label="Make Landmark"
+     layout="topleft"
+     name="Make Landmark">
+        <menu_item_call.on_click
+         function="TeleportHistory.MakeLandmark" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ecc1d8a954b5cda2fbf6620d1e53362c4f8805c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Teleport History Item Context Menu">
+    <menu_item_call
+     label="Open"
+     layout="topleft"
+     name="TabOpen">
+        <menu_item_call.on_click
+         function="TeleportHistory.TabOpen" />
+    </menu_item_call>
+    <menu_item_call
+     label="Close"
+     layout="topleft"
+     name="TabClose">
+        <menu_item_call.on_click
+         function="TeleportHistory.TabClose" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 10aa23b71575b1a237c5a2a997bb9fd2bb8855b4..2c77f61da68720b3a0f9e988338f3febc0c8fa46 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -128,13 +128,13 @@
                  function="World.SetAway" />
             </menu_item_call>
             <menu_item_separator
-				layout="topleft"/>
+             layout="topleft"/>
             <menu_item_call
              label="Set Busy"
              layout="topleft"
              name="Set Busy">
                 <menu_item_call.on_click
-					function="World.SetBusy"/>
+                 function="World.SetBusy"/>
             </menu_item_call>
         </menu>
         <menu_item_separator
@@ -1041,15 +1041,6 @@
         </menu_item_check>
         <menu_item_separator
              layout="topleft" />
-        <menu_item_call
-             label="Report Bug..."
-             layout="topleft"
-             name="ReportBug">
-            <menu_item_call.on_click
-                 function="PromptShowURL"
-                 name="ReportBug_url"
-                 parameter="hud,http://help.secondlife.com/en/bugreport/" />
-        </menu_item_call>
         <menu_item_call
              label="Report Abuse..."
              layout="topleft"
@@ -2771,15 +2762,6 @@
                  function="Advanced.ShowDebugSettings"
                  parameter="skin" />
             </menu_item_call>
-            <menu_item_check
-             label="Editable UI"
-             layout="topleft"
-             name="Editable UI">
-                <menu_item_check.on_check
-                 function="Advanced.CheckEditableUI" />
-                <menu_item_check.on_click
-                 function="Advanced.ToggleEditableUI" />
-            </menu_item_check>
             <menu_item_call
              label="Dump SelectMgr"
              layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 044194a4ed4ca3807cd76f9ee4864e8d98e2dac1..fe088b43be2a2cf3578af2c171ba9766755051aa 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -646,6 +646,19 @@ This entire region is damage enabled.
 Scripts must be allowed to run for weapons to work.
   </notification>
 
+<notification
+   icon="alertmodal.tga"
+   name="MultipleFacesSelected"
+   type="alertmodal">
+         Multiple faces are currently selected. 
+If you continue this action, separate instances of media will be set on multiple faces of the object.
+To place the media on only one face, choose Select Texture and click on the desired face of that object then click Add.
+    <usetemplate
+	 name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="MustBeInParcel"
@@ -783,6 +796,20 @@ There is no reimbursement for fees paid.
      yestext="OK"/>
   </notification>
 
+
+<notification
+   icon="alertmodal.tga"
+   name="DeleteMedia"
+   type="alertmodal">
+You have selected to delete the media associated with this face.
+Are you sure you want to continue?
+    <usetemplate
+     ignoretext="Confirm before I delete media from an object"
+     name="okcancelignore"
+     notext="No"
+     yestext="Yes"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="ClassifiedSave"
@@ -1215,7 +1242,7 @@ Please move all objects to be acquired onto the same region.
    type="alertmodal">
 [EXTRA]
 
-Go to [_URL] for information on purchasing currency?
+Go to [_URL] for information on purchasing L$?
     <url option="0" name="url">
 
 			http://secondlife.com/app/currency/
@@ -1691,7 +1718,6 @@ No Group selected.
    type="alertmodal">
 Unable to deed land:
 Cannot find the region this land is in.
-Please use Help &gt; Report Bug to report this.
   </notification>
 
   <notification
@@ -1772,8 +1798,6 @@ Parcels you own appear in green.
    type="alertmodal">
 Unable to abandon land:
 Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
   </notification>
 
   <notification
@@ -1846,8 +1870,6 @@ Divide land?
    type="alertmodal">
 Unable to divide land:
 Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
   </notification>
 
   <notification
@@ -1856,8 +1878,6 @@ Please use Help &gt; Report Bug to report this.
    type="alertmodal">
 Unable to join land:
 Cannot find the region this land is in.
-
-Please use Help &gt; Report Bug to report this.
   </notification>
 
   <notification
@@ -1973,8 +1993,6 @@ Unable to save &apos;[NAME]&apos; to wearable file.  You will need to free up so
    type="alertmodal">
 Unable to save [NAME] to central asset store.
 This is usually a temporary failure. Please customize and save the wearable again in a few minutes.
-
-If this problem persists, please click on Help &gt; Report Bug and provide details about your network setup.
   </notification>
 
   <notification
@@ -2756,18 +2774,6 @@ Go to secondlife.com to manage your account?
      yestext="OK"/>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="WebLaunchBugReport101"
-   type="alertmodal">
-Visit the [SECOND_LIFE] Wiki and learn how to report bugs correctly.
-    <usetemplate
-     ignoretext="Launch my browser to learn how to report a Bug"
-     name="okcancelignore"
-     notext="Cancel"
-     yestext="OK"/>
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="WebLaunchSecurityIssues"
@@ -4273,22 +4279,6 @@ The resolution of this report applies only to this Region. Residents&apos; acces
   <unique/>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="HelpReportBug"
-   type="alertmodal">
-Use this tool to *only* report technical features that do not perform as described or expected, please provide as much detail as possible.
-You may reply to the auto-response email to add more details to your report.
-
-All bug reports are investigated and assessed. No email response will be sent.
-
-If you are having a technical difficulty, please contact Support at:
-
-http://secondlife.com/community/support.php
-
-Note: Incomplete reports will not be investigated
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseSelectCategory"
@@ -4297,14 +4287,6 @@ Please select a category for this abuse report.
 Selecting a category helps us file and process abuse reports.
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="HelpReportBugSelectCategory"
-   type="alertmodal">
-Please select a category for this bug.
-Selecting a category helps us file and process bug reports.
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseAbuserNameEmpty"
@@ -4329,14 +4311,6 @@ Please enter a summary of the abuse that took place.
 Entering an accurate summary helps us file and process abuse reports.
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="HelpReportBugSummaryEmpty"
-   type="alertmodal">
-Please enter a summary of the bug.
-Entering an accurate summary helps us file and process bug reports.
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseDetailsEmpty"
@@ -4346,15 +4320,6 @@ Be as specific as you can, including names and the details of the incident you a
 Entering an accurate description helps us file and process abuse reports.
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="HelpReportBugDetailsEmpty"
-   type="alertmodal">
-Please enter a detailed description of the bug.
-Be as specific as you can, including steps to reproduce the bug if possible.
-Entering an accurate description helps us file and process bug reports.
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseContainsCopyright"
@@ -6547,6 +6512,17 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
 Unable to find the help topic for this element.
   </notification>
 
+    <notification
+ icon="alertmodal.tga"
+ name="ObjectMediaFailure"
+ type="alertmodal">
+Server Error: Media update or get failed.
+&apos;[ERROR]&apos;
+        <usetemplate
+         name="okbutton"
+         yestext="OK"/>
+    </notification>
+
   <global name="UnsupportedCPU">
 - Your CPU speed does not meet the minimum requirements.
   </global>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 90b331a39f76be618b7c666c64e70c8a316ad778..cd7e340ff1af7fc6fa366ab645f925389a1b2624 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -79,7 +79,6 @@
              label="Move"
              layout="topleft"
              name="movement_btn"
-             tab_stop="false"
              tool_tip="Shows/Hide Movement controls" 
              top="6"
              width="70">
@@ -117,7 +116,6 @@
              label="View"
              layout="topleft"
              left="0"
-             tab_stop="false"
              tool_tip="Shows/Hide Camera controls" 
              top="6"
              name="camera_btn"
@@ -133,7 +131,6 @@
              height="20"
              width="20"
              left_pad="0"
-             tab_stop="false"
              is_toggle="true"
              picture_style="true"
          	 image_selected="toggle_button_selected"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index c4c8aa24c44c9eecd97ebad9f8712752462798ef..fb4ce436e8c77caf5c844ddba56463e127705638 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -28,7 +28,7 @@
      width="25"
      height="25"
      label=""
-     follows="top|left"
+     follows="top|right"
      image_overlay="BackArrow_Off"
      tab_stop="false" />
     <text
@@ -41,6 +41,7 @@
      text_color="white"
      follows="top|left|right"
      mouse_opaque="true"
+     use_ellipses="true"
      name="group_name">(Loading...)</text>
     <line_editor
      follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index e7fb3fa208beeb035d2446807556357ba8473dc9..c96c296057294cffe5bc2228806ccf4da9ae420c 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -26,9 +26,8 @@
      layout="topleft"
      left="0"
      name="login_html"
-     hide_loading="true"
      right="-1"
-     start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E"
+     start_url=""
      top="1" />
     <text
      type="string"
@@ -52,7 +51,7 @@
      max_length="31"
      name="first_name_edit"
      select_on_focus="true"
-     tool_tip="Second Life First Name"
+     tool_tip="[SECOND_LIFE] First Name"
      top_pad="2"
      width="120" />
     <text
@@ -78,6 +77,7 @@
      max_length="31"
      name="last_name_edit"
      select_on_focus="true"
+     tool_tip="[SECOND_LIFE] Last Name"
      top_pad="2"
      width="120" />
     <text
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b66aad18532d5b4afd0e2c0e2eac14f95b049d16
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel 
+ border="true" 
+ enabled="true" 
+ follows="left|top|right|bottom"
+ height="500" 
+ label="General" 
+ left="102" 
+ mouse_opaque="true"
+ name="Media Settings General" 
+ width="365">
+	
+  <text 
+   bottom_delta="-17" 
+   follows="top|left" 
+   height="15" 
+   left="10" 
+   name="">
+    Home URL:
+  </text>
+  <line_editor 
+   bottom_delta="-21" 
+   enabled="true" 
+   follows="left|top" 
+   font="SansSerif"
+   height="20" 
+   left="10" 
+   name="home_url"
+   tool_tip="The home URL for this media source"
+   width="340"> 
+    <!--  <line_editor.commit_callback
+	     function="Media.CommitHomeURL"/> -->
+  </line_editor>
+  <text 
+   bottom_delta="-20" 
+   follows="top|left" 
+   height="15" 
+   left="10" 
+   name="current_url_label">
+    Current URL:
+  </text>
+  <line_editor 
+   bottom_delta="-20" 
+   enabled="false" 
+   follows="left|top" 
+   font="SansSerif"
+   height="20" 
+   left="10" 
+   name="current_url"
+   tool_tip="The current URL for this media source"
+   value="" 
+   width="340" />
+  <button 
+   bottom_delta="-20" 
+   follows="top|left" 
+   height="20" 
+   label="Reset"
+   left_delta="233" 
+   name="current_url_reset_btn" 
+   width="110" > 
+   <button.commit_callback
+	     function="Media.ResetCurrentUrl"/>
+  </button>
+
+  <web_browser 
+   border_visible="false" 
+   bottom_delta="-120" 
+   follows="top|left"
+   left="120" 
+   name="preview_media" 
+   width="128" 
+   height="128" 
+   start_url="about:blank" 
+   decouple_texture_size="true" />
+
+  <text 
+   bottom_delta="-15" 
+   follows="top|left" 
+   height="15" 
+   left="164" 
+   name="">
+    Preview
+  </text>
+
+  <text 
+   bottom_delta="-20" 
+   follows="top|left" 
+   height="15"
+   left="10" 
+   name="">
+    Controls:
+  </text>
+  <combo_box 
+   allow_text_entry="false" 
+   bottom_delta="-20" 
+   enabled="true" 
+   follows="left|top"
+   height="18" 
+   left="10" 
+   max_chars="20" 
+   mouse_opaque="true"
+   name="controls" 
+   width="120">
+    <combo_item 
+	 type="string" 
+	 length="1" 
+	 enabled="true" 
+	 name="Standard" 
+	 value="Standard">
+      Standard
+    </combo_item>
+    <combo_item 
+	 type="string" 
+	 length="1" 
+	 enabled="true" 
+	 name="Mini" 
+	 value="Mini">
+      Mini
+    </combo_item>
+  </combo_box>
+
+  <check_box 
+   bottom_delta="-25" 
+   enabled="true" 
+   follows="left|top" 
+   font="SansSerifSmall"
+   height="16"
+   initial_value="false"
+   label="Auto Loop" 
+   left="10" 
+   mouse_opaque="true"
+   name="auto_loop" 
+   radio_style="false" 
+   width="150" />
+
+  <check_box 
+   bottom_delta="-25" 
+   enabled="true" 
+   follows="left|top" 
+   font="SansSerifSmall"
+   height="16" 
+   initial_value="false"
+   label="First Click Interacts" 
+   left_delta="0" 
+   mouse_opaque="true"
+   name="first_click_interact" 
+   radio_style="false" 
+   width="150" />
+
+  <check_box 
+   bottom_delta="-25" 
+   enabled="true" 
+   follows="left|top"
+   font="SansSerifSmall"
+   height="16" 
+   initial_value="false"
+   label="Auto Zoom" 
+   left_delta="0" 
+   mouse_opaque="true"
+   name="auto_zoom" 
+   radio_style="false" 
+   width="150" />
+
+  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+	     height="16" initial_value="false"
+	     label="Use Default Alternative Image" left="10" mouse_opaque="true"
+	     name="alt_image_enable" radio_style="false" width="150" />
+
+  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+	     height="16" initial_value="false"
+	     label="Auto Play Media" left="10" mouse_opaque="true"
+	     name="auto_play" radio_style="false" width="150" />
+  <text bottom_delta="-14" follows="top|left" height="15" left="30" width="340" 
+        enabled="false" name="">
+    Note: Parcel Owners &amp; Residents can override this setting
+  </text>
+
+  <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
+	     height="16" initial_value="false"
+	     label="Auto Scale Media on Face of Object" left="10" mouse_opaque="true"
+	     name="auto_scale" radio_style="false" width="150" />
+  <text bottom_delta="-20" follows="top|left" height="15" left="30" name="">
+    Size:
+  </text>
+  <spinner bottom_delta="0"
+	     decimal_digits="0" enabled="true" follows="left|top" height="16"
+	     increment="1" initial_val="256" label="" label_width="0"
+	     left_delta="40" max_val="2000" min_val="0" mouse_opaque="true"
+	     name="width_pixels" width="50" />
+  <text bottom_delta="0" follows="top|left" height="15" left_delta="60" name="">
+    X
+  </text>
+  <spinner bottom_delta="0"
+	     decimal_digits="0" enabled="true" follows="left|top" height="16"
+	     increment="1" initial_val="256" label="" label_width="0"
+	     left_delta="20" max_val="2000" min_val="0" mouse_opaque="true"
+	     name="height_pixels" width="50" />
+ 
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f11364874a168e48697bbc557451edd36f47df3c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel border="true" enabled="true" follows="left|top|right|bottom"
+    height="500" label="Controls" left="102" mouse_opaque="true"
+    name="Media settings for controls" width="365">
+
+  <text bottom_delta="-50" follows="top|left" height="15" left="10" name="" enabled="false">
+    Owner
+  </text>
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+         name="perms_owner_interact" radio_style="false" width="250" />
+
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Hide Control Bar" left="30" mouse_opaque="true"
+         name="perms_owner_control" radio_style="false" width="250" />
+
+  <text bottom_delta="-36" follows="top|left" height="15" left="10" name="perms_group_name_label" enabled="false">
+    Group
+  </text>
+  <name_box bottom_delta="-5" enabled="false" follows="left|top" font="SansSerif"
+	     height="20" left="60" name="perms_group_name"
+       value ="" 
+	     width="200" />
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+         name="perms_group_interact" radio_style="false" width="250" />
+
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Hide Control Bar" left="30" mouse_opaque="true"
+         name="perms_group_control" radio_style="false" width="250" />
+
+  <text bottom_delta="-36" follows="top|left" height="15" left="10" name="" enabled="false">
+    Anyone
+  </text>
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
+         name="perms_anyone_interact" radio_style="false" width="250" />
+
+  <check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
+         height="16" initial_value="false"
+         label="Hide Control Bar" left="30" mouse_opaque="true"
+         name="perms_anyone_control" radio_style="false" width="250" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_security.xml b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
new file mode 100644
index 0000000000000000000000000000000000000000..695e956e41b1b363f800a5c3c5dbf3403fd2ebce
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel 
+ border="true" 
+ enabled="true" 
+ follows="left|top|right|bottom"
+ height="500" 
+ label="Security" 
+ left="102" 
+ mouse_opaque="true"
+ name="Media Settings Security" 
+ width="365">
+  <check_box 
+   bottom_delta="-40" 
+   enabled="true" 
+   follows="left|top" 
+   font="SansSerifSmall"
+   height="16" 
+   initial_value="false"
+   label="Only Allow Access to Specified URLs (by prefix)" 
+   left="10" 
+   mouse_opaque="true"
+   name="whitelist_enable" 
+   radio_style="false" 
+   width="250" />
+  <scroll_list 
+   follows="top|left" 
+   height="200" 
+   left="30" 
+   name="whitelist" 
+   width="315" 
+   enabled="true" />
+  <button 
+   bottom_delta="-30" 
+   follows="top|left" 
+   height="20" 
+   label="Add"
+   left="30" 
+   name="whitelist_add" 
+   width="70" 
+   enabled="true"> 
+     <button.commit_callback
+	     function="Media.whitelistAdd"/>
+  </button>
+  <button 
+   bottom_delta="0" 
+   follows="top|left" 
+   height="20" 
+   label="Delete"
+   left="275" 
+   name="whitelist_del" 
+   width="70" 
+   enabled="true"> 
+     <button.commit_callback
+	     function="Media.whitelistDelete"/>
+  </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 683a54b3662ce24ddfe9ec83339f6f31f8692919..4088d96ebf50c0fb23e738b5695898131fc69afa 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -35,6 +35,8 @@
      follows="right"
      height="20"
      speak_button.font="SansSerifMedium"
+     speak_button.tab_stop="true"
+     show_button.tab_stop="true"
      layout="topleft"
      left_pad="5"
      name="talk"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 58ebac2a8424ab4a883a1f68dabb989caa0dbd46..2056ec14d525bc91024b1425fdbe9fbb8d85f760 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="in"
  follows="left|top|right|bottom"
- height="420"
+ height="460"
  label="Notes &amp; Privacy"
  layout="topleft"
  left="0"
@@ -16,7 +16,7 @@
      layout="topleft"
      left="0"
      top="0"
-     height="420"
+     height="430"
      width="313"
      border_size="0">
         <panel
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index d0bde77cf2901b67e3ec8e67eec0cb7cb94cee2c..1bd19533972c86968c76834f7cfeb3d7217e1b83 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="left|top|right|bottom"
- height="515"
+ height="555"
  label="Picks"
  layout="topleft"
  left="0"
@@ -11,7 +11,7 @@
         <flat_list_view
          color="DkGray2"
          follows="left|top|right|bottom"
-         height="495"
+         height="465"
          layout="topleft"
          left="0"
          name="picks_list"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 8f710545d5618aef1936a9e428341b910c6974cc..06ecfdc995910666a3cea18e9dc6a3921781b207 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -261,17 +261,17 @@ My Avatar:
      label="Show script errors"
      layout="topleft"
      left="30"
-     name="first_person_avatar_visible"
+     name="show_script_errors"
      width="256"
      top_pad="10"/>
     <radio_group
-	 enabled_control="EnableVoiceChat"
-	 control_name="VoiceEarLocation"
+	 enabled_control="EnableShowScriptErrors"
+	 control_name="ShowScriptErrorsLocation"
      draw_border="false"
      height="40"
      layout="topleft"
      left_delta="50"
-     name="ear_location"
+     name="show_location"
      top_pad="5"
      width="364">
         <radio_item
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 56ba5970f20a9f682b9ecc103c678f2923c8cc9b..02d179d5032eaccbbca67ad7cda2eb5b956b2895 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="all"
- height="515"
+ height="560"
  label="Profile"
  layout="topleft"
  left="0"
@@ -25,7 +25,7 @@
     <scroll_container
      color="DkGray2"
      follows="left|top|right|bottom"
-     height="515"
+     height="500"
      min_height="300"
      layout="topleft"
      name="profile_scroll"
@@ -265,6 +265,7 @@
      left="0"
      name="profile_buttons_panel"
      top_pad="0"
+     height="25"
      width="313">
         <button
          follows="bottom|left"
@@ -316,6 +317,7 @@
      name="profile_me_buttons_panel"
      top_pad="0"
      visible="false"
+     height="25"
      width="313">
         <button
          follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index cbe646f3cca774e7b3c2a3bb6c9d832d342a4151..606535115d3c26c2d90e3da74fb8c0b5d456408c 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -2,7 +2,7 @@
 <panel
  background_visible="true"
  follows="all"
- height="660"
+ height="570"
  layout="topleft"
  min_height="350"
  min_width="240"
@@ -50,7 +50,7 @@
      width="25" />
     <tab_container
      follows="left|top|right|bottom"
-     height="660"
+     height="560"
      layout="topleft"
      left="10"
      name="tabs"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 5738879c5a53281d47cf4cb98ca06bff87a0d182..a3c714ce72da80657df0ce677e4e1d6014d441a3 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -184,9 +184,9 @@
              layout="topleft"
              name="Help..." />
             <menu_item_call
-             label="LSL Wiki Help..."
+             label="Keyword Help..."
              layout="topleft"
-             name="LSL Wiki Help..." />
+             name="Keyword Help..." />
         </menu>
     </menu_bar>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
index f25c4bfbbaac44f4d1a23283e82384f20373d1ed..aa76a61c1512f13e3816f76c92c77e4a93d593ae 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
@@ -19,4 +19,17 @@
      top="4"
      value="Side Panel"
      width="255" />
+    <button
+     follows="left|right|top"
+     font="SansSerif"
+     height="23"
+     label="?"
+     layout="topleft"
+     name="show_help"
+     top="5"
+     right="-8"
+     width="28">
+        <button.commit_callback
+         function="Button.ShowHelp" />
+    </button>
 </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 c1785542879edee2fde56a565a2d8fbd4735d86b..f6ffd2e4ee9dafc70e33072f75e099e755979112 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -52,7 +52,7 @@
      left="-210"
      name="buycurrency"
      picture_style="true"
-     tool_tip="My Balance / Buy currency"
+     tool_tip="My Balance / Buy L$"
      top="0"
      width="117" />
     <text
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index a0fc9864237ca71398b5585e5be059c69d44bab1..aa95a2baefee23a9355329a4dfe18ca02de891e5 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -111,7 +111,7 @@
              width="380">
 	    </flat_list_view>
 	</accordion_tab>     
-     
+          
         <accordion_tab
          can_resize="false"
          layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 13a53a4ce3b4151e6cc6237a1bc8d94bbdd1458f..1e85cac5394ef9fed2336cdcf630bdd05ad1d83b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -93,7 +93,6 @@
 	<string name="BUTTON_RESTORE">Restore</string>			
 	<string name="BUTTON_MINIMIZE">Minimize</string>
 	<string name="BUTTON_TEAR_OFF">Tear Off</string>
-	<string name="BUTTON_EDIT">Edit</string>
 	<string name="BUTTON_DOCK">Dock</string>
 	<string name="BUTTON_UNDOCK">Undock</string>
 	<string name="BUTTON_HELP">Show Help</string>
@@ -308,112 +307,115 @@ Sleeps script for [SLEEP_TIME] seconds.
 	
 	<string name="LSLTipText_llSin">
 float llSin(float theta)
-theta in radians
+Returns the sine of theta (theta in radians)
 	</string>
 	<string name="LSLTipText_llCos">
 float llCos(float theta)
-theta in radians
+Returns the cosine of theta (theta in radians)
 	</string>
 	<string name="LSLTipText_llTan">
 float llTan(float theta)
-theta radians
+Returns the tangent of theta (theta in radians)
 	</string>
 	<string name="LSLTipText_llAtan2">
 float llAtan2(float y, float x)
+Returns the arctangent2 of y, x
 	</string>
 	<string name="LSLTipText_llSqrt">
 float llSqrt(float val)
-returns 0 and triggers a Math Error for imaginary results
+Returns the square root of val, or returns 0 and triggers a Math Error for imaginary results
 	</string>
 	<string name="LSLTipText_llPow">
 float llPow(float base, float exponent)
-returns 0 and triggers Math Error for imaginary results
+Returns the base raised to the power exponent, or returns 0 and triggers Math Error for imaginary results
 	</string>
 	<string name="LSLTipText_llAbs">
 integer llAbs(integer val)
+Returns the positive version of val
 	</string>
 	<string name="LSLTipText_llFabs">
 float llFabs(float val)
+Returns the positive version of val
 	</string>
 	<string name="LSLTipText_llFrand">
 float llFrand(float mag)
-returns random number in range [0,mag)
+Returns a pseudo random number in the range [0,mag) or (mag,0]
 	</string>
 	<string name="LSLTipText_llFloor">
 integer llFloor(float val)
-returns largest integer value &lt;= val
+Returns largest integer value &lt;= val
 	</string>
 	<string name="LSLTipText_llCeil">
 integer llCeil(float val)
-returns smallest integer value &gt;= val
+Returns smallest integer value &gt;= val
 	</string>
 	<string name="LSLTipText_llRound">
 integer llRound(float val)
-returns val rounded to the nearest integer
+Returns val rounded to the nearest integer
 	</string>
 	<string name="LSLTipText_llVecMag">
 float llVecMag(vector v)
-returns the magnitude of v
+Returns the magnitude of v
 	</string>
 	<string name="LSLTipText_llVecNorm">
 vector llVecNorm(vector v)
-returns the v normalized
+Returns the v normalized
 	</string>
 	<string name="LSLTipText_llVecDist">
 float llVecDist(vector v1, vector v2)
-returns the 3D distance between v1 and v2
+Returns the 3D distance between v1 and v2
 	</string>
 	<string name="LSLTipText_llRot2Euler">
 vector llRot2Euler(rotation q)
-returns the Euler representation (roll, pitch, yaw) of q
+Returns the Euler representation (roll, pitch, yaw) of q
 	</string>
 	<string name="LSLTipText_llEuler2Rot">
 rotation llEuler2Rot(vector v)
-returns the rotation representation of Euler Angles v
+Returns the rotation representation of Euler Angles v
 	</string>
 	<string name="LSLTipText_llAxes2Rot">
 rotation llAxes2Rot(vector fwd, vector left, vector up)
-returns the rotation defined by the coordinate axes
+Returns the rotation defined by the coordinate axes
 	</string>
 	<string name="LSLTipText_llRot2Fwd">
 vector llRot2Fwd(rotation q)
-returns the forward vector defined by q
+Returns the forward vector defined by q
 	</string>
 	<string name="LSLTipText_llRot2Left">
 vector llRot2Left(rotation q)
-returns the left vector defined by q
+Returns the left vector defined by q
 	</string>
 	<string name="LSLTipText_llRot2Up">
 vector llRot2Up(rotation q)
-returns the up vector defined by q
+Returns the up vector defined by q
 	</string>
 	<string name="LSLTipText_llRotBetween">
 rotation llRotBetween(vector v1, vector v2)
-returns the rotation to rotate v1 to v2
+Returns the rotation to rotate v1 to v2
 	</string>
 	<string name="LSLTipText_llWhisper">
 llWhisper(integer channel, string msg)
-whispers msg on channel
+Whispers the text of msg on channel
 	</string>
 	<string name="LSLTipText_llSay">
 llSay(integer channel, string msg)
-says msg on channel
+Says the text of msg on channel
 	</string>
 	<string name="LSLTipText_llShout">
 llShout(integer channel, string msg)
-shouts msg on channel
+Shouts the text of msg on channel
 	</string>
 	<string name="LSLTipText_llListen">
 integer llListen(integer channel, string name, key id, string msg)
-sets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen
+Sets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen
 	</string>
 	<string name="LSLTipText_llListenControl">
 llListenControl(integer number, integer active)
-makes a listen event callback active or inactive
+Makes a listen event callback active or inactive
 	</string>
 	<string name="LSLTipText_llListenRemove">
 llListenRemove(integer number)
-removes listen event callback number
+Removes listen event callback number
 	</string>
 	<string name="LSLTipText_llSensor">
 llSensor(string name, key id, integer type, float range, float arc)
@@ -421,43 +423,43 @@ Performs a single scan for name and id with type (AGENT, ACTIVE, PASSIVE, and/or
 	</string>
 	<string name="LSLTipText_llSensorRepeat">
 llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)
-sets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds
+Sets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds
 	</string>
 	<string name="LSLTipText_llSensorRemove">
 llSensorRemove()
-removes sensor
+Removes the sensor setup by llSensorRepeat
 	</string>
 	<string name="LSLTipText_llDetectedName">
 string llDetectedName(integer number)
-returns the name of detected object number (returns empty string if number is not valid sensed object)
+Returns the name of detected object number (returns empty string if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedKey">
 key llDetectedKey(integer number)
-returns the key of detected object number (returns empty key if number is not valid sensed object)
+Returns the key of detected object number (returns empty key if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedOwner">
 key llDetectedOwner(integer number)
-returns the key of detected object&apos;s owner (returns empty key if number is not valid sensed object)
+Returns the key of detected object&apos;s owner (returns empty key if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedType">
 integer llDetectedType(integer number)
-returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)
+Returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedPos">
 vector llDetectedPos(integer number)
-returns the position of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the position of detected object number (returns &lt;0,0,0&gt; if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedVel">
 vector llDetectedVel(integer number)
-returns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedGrab">
 vector llDetectedGrab(integer number)
-returns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not valid sensed object)
+Returns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedRot">
 rotation llDetectedRot(integer number)
-returns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not valid sensed object)
+Returns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not a valid sensed object)
 	</string>
 	<string name="LSLTipText_llDetectedGroup">
 integer llDetectedGroup(integer number)
@@ -465,127 +467,127 @@ Returns TRUE if detected object is part of same group as owner
 	</string>
 	<string name="LSLTipText_llDetectedLinkNumber">
 integer llDetectedLinkNumber(integer number)
-returns the link position of the triggered event for touches and collisions only
+Returns the link position of the triggered event for touches and collisions only
 	</string>
 	<string name="LSLTipText_llDie">
 llDie()
-deletes the object
+Deletes the object
 	</string>
 	<string name="LSLTipText_llGround">
-float llGround(vector v)
-returns the ground height below the object position + v
+float llGround(vector offset)
+Returns the ground height below the object position + offset
 	</string>
 	<string name="LSLTipText_llCloud">
-float llCloud(vector v)
-returns the cloud density at the object position + v
+float llCloud(vector offset)
+Returns the cloud density at the object position + offset
 	</string>
 	<string name="LSLTipText_llWind">
-vector llWind(vector v)
-returns the wind velocity at the object position + v
+vector llWind(vector offset)
+Returns the wind velocity at the object position + offset
 	</string>
 	<string name="LSLTipText_llSetStatus">
 llSetStatus(integer status, integer value)
-sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
+Sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
 	</string>
 	<string name="LSLTipText_llGetStatus">
 integer llGetStatus(integer status)
-gets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)
+Returns value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)
 	</string>
 	<string name="LSLTipText_llSetScale">
 llSetScale(vector scale)
-sets the scale
+Sets the scale of the prim
 	</string>
 	<string name="LSLTipText_llGetScale">
 vector llGetScale()
-gets the scale
+Returns the scale of the prim
 	</string>
 	<string name="LSLTipText_llSetColor">
 llSetColor(vector color, integer face)
-sets the color
+Sets the color on face of the prim
 	</string>
 	<string name="LSLTipText_llGetAlpha">
 float llGetAlpha(integer face)
-gets the alpha
+Returns the alpha of face
 	</string>
 	<string name="LSLTipText_llSetAlpha">
 llSetAlpha(float alpha, integer face)
-sets the alpha
+Sets the alpha on face
 	</string>
 	<string name="LSLTipText_llGetColor">
 vector llGetColor(integer face)
-gets the color
+Returns the color on face
 	</string>
 	<string name="LSLTipText_llSetTexture">
 llSetTexture(string texture, integer face)
-sets the texture of face
+Sets the texture of face or ALL_SIDES
 	</string>
 	<string name="LSLTipText_llScaleTexture">
-llScaleTexture(float scales, float scalet, integer face)
-sets the texture s, t scales for the chosen face
+llScaleTexture(float u, float v, integer face)
+Sets the texture u &amp; v scales for the chosen face or ALL_SIDES
 	</string>
 	<string name="LSLTipText_llOffsetTexture">
-llOffsetTexture(float offsets, float offsett, integer face)
-sets the texture s, t offsets for the chosen face
+llOffsetTexture(float u, float v, integer face)
+Sets the texture u &amp; v offsets for the chosen face or ALL_SIDES
 	</string>
 	<string name="LSLTipText_llRotateTexture">
 llRotateTexture(float rotation, integer face)
-sets the texture rotation for the chosen face
+Sets the texture rotation for the chosen face
 	</string>
 	<string name="LSLTipText_llGetTexture">
 string llGetTexture(integer face)
-gets the texture of face (if it&apos;s a texture in the object inventory, otherwise the key in a string)
+Returns a string that is the texture on face (the inventory name if it is a texture in the prim&apos;s inventory, otherwise the key)
 	</string>
 	<string name="LSLTipText_llSetPos">
 llSetPos(vector pos)
-sets the position (if the script isn&apos;t physical)
+Moves the object or prim towards pos without using physics (if the script isn&apos;t physical)
 	</string>
 	<string name="LSLTipText_llGetPos">
 vector llGetPos()
-gets the position (if the script isn&apos;t physical)
+Returns the position of the task in region coordinates
 	</string>
 	<string name="LSLTipText_llGetLocalPos">
 vector llGetLocalPos()
-gets the position relative to the root (if the script isn&apos;t physical)
+Returns the position relative to the root
 	</string>
 	<string name="LSLTipText_llSetRot">
 llSetRot(rotation rot)
-sets the rotation (if the script isn&apos;t physical)
+Sets the rotation
 	</string>
 	<string name="LSLTipText_llGetRot">
 rotation llGetRot()
-gets the rotation (if the script isn&apos;t physical)
+Returns the rotation relative to the region&apos;s axes
 	</string>
 	<string name="LSLTipText_llGetLocalRot">
 rotation llGetLocalRot()
-gets the rotation local to the root (if the script isn&apos;t physical)
+Returns the rotation local to the root
 	</string>
 	<string name="LSLTipText_llSetForce">
 llSetForce(vector force, integer local)
-sets force on object, in local coords if local == TRUE (if the script is physical)
+Applies force to the object (if the script is physical), in local coords if local == TRUE
 	</string>
 	<string name="LSLTipText_llGetForce">
 vector llGetForce()
-gets the force (if the script is physical)
+Returns the force (if the script is physical)
 	</string>
 	<string name="LSLTipText_llTarget">
 integer llTarget(vector position, float range)
-set positions within range of position as a target and return an ID for the target
+Sets positions within range of position as a target and return an ID for the target
 	</string>
 	<string name="LSLTipText_llTargetRemove">
 llTargetRemove(integer number)
-removes target number
+Removes positional target number registered with llTarget
 	</string>
 	<string name="LSLTipText_llRotTarget">
 integer llRotTarget(rotation rot, float error)
-set rotations with error of rot as a rotational target and return an ID for the rotational target
+Set rotations with error of rot as a rotational target and return an ID for the rotational target
 	</string>
 	<string name="LSLTipText_llRotTargetRemove">
 llRotTargetRemove(integer number)
-removes rotational target number
+Removes rotational target number registered with llRotTarget
 	</string>
 	<string name="LSLTipText_llMoveToTarget">
 llMoveToTarget(vector target, float tau)
-critically damp to target in tau seconds (if the script is physical)
+Critically damps to target in tau seconds (if the script is physical)
 	</string>
 	<string name="LSLTipText_llStopMoveToTarget">
 llStopMoveToTarget()
@@ -593,83 +595,83 @@ Stops critically damped motion
 	</string>
 	<string name="LSLTipText_llApplyImpulse">
 llApplyImpulse(vector force, integer local)
-applies impulse to object, in local coords if local == TRUE (if the script is physical)
+Applies impulse to object (if the script is physical), in local coords if local == TRUE
 	</string>
 	<string name="LSLTipText_llApplyRotationalImpulse">
 llApplyRotationalImpulse(vector force, integer local)
-applies rotational impulse to object, in local coords if local == TRUE (if the script is physical)
+Applies rotational impulse to object (if the script is physical), in local coords if local == TRUE
 	</string>
 	<string name="LSLTipText_llSetTorque">
 llSetTorque(vector torque, integer local)
-sets the torque of object, in local coords if local == TRUE (if the script is physical)
+Sets the torque of object (if the script is physical), in local coords if local == TRUE
 	</string>
 	<string name="LSLTipText_llGetTorque">
 vector llGetTorque()
-gets the torque (if the script is physical)
+Returns the torque (if the script is physical)
 	</string>
 	<string name="LSLTipText_llSetForceAndTorque">
 llSetForceAndTorque(vector force, vector torque, integer local)
-sets the force and torque of object, in local coords if local == TRUE (if the script is physical)
+Sets the force and torque of object (if the script is physical), in local coords if local == TRUE
 	</string>
 	<string name="LSLTipText_llGetVel">
 vector llGetVel()
-gets the velocity
+Returns the velocity of the object
 	</string>
 	<string name="LSLTipText_llGetAccel">
 vector llGetAccel()
-gets the acceleration
+Returns the acceleration of the object relative to the region&apos;s axes
 	</string>
 	<string name="LSLTipText_llGetOmega">
 vector llGetOmega()
-gets the omega
+Returns the rotation velocity in radians per second
 	</string>
 	<string name="LSLTipText_llGetTimeOfDay">
 float llGetTimeOfDay()
-gets the time in seconds since [SECOND_LIFE] server midnight (or since server up-time; whichever is smaller)
+Returns the time in seconds since [SECOND_LIFE] server midnight or since region up-time, whichever is smaller
 	</string>
 	<string name="LSLTipText_llGetWallclock">
 float llGetWallclock()
-gets the time in seconds since midnight
+Returns the time in seconds since midnight California Pacific time (PST/PDT)
 	</string>
 	<string name="LSLTipText_llGetTime">
 float llGetTime()
-gets the time in seconds since creation
+Returns the time in seconds since the last region reset, script reset, or call to either llResetTime or llGetAndResetTime
 	</string>
 	<string name="LSLTipText_llResetTime">
 llResetTime()
-sets the time to zero
+Sets the script timer to zero
 	</string>
 	<string name="LSLTipText_llGetAndResetTime">
 float llGetAndResetTime()
-gets the time in seconds since creation and sets the time to zero
+Returns the script time in seconds and then resets the script timer to zero
 	</string>
 	<string name="LSLTipText_llSound">
 llSound(string sound, float volume, integer queue, integer loop)
-plays sound at volume and whether it should loop or not
+Plays sound at volume and whether it should loop or not
 	</string>
 	<string name="LSLTipText_llPlaySound">
 llPlaySound(string sound, float volume)
-plays attached sound once at volume (0.0 - 1.0)
+Plays attached sound once at volume (0.0 - 1.0)
 	</string>
 	<string name="LSLTipText_llLoopSound">
 llLoopSound(string sound, float volume)
-plays attached sound looping indefinitely at volume (0.0 - 1.0)
+Plays attached sound looping indefinitely at volume (0.0 - 1.0)
 	</string>
 	<string name="LSLTipText_llLoopSoundMaster">
 llLoopSoundMaster(string sound, float volume)
-plays attached sound looping at volume (0.0 - 1.0), declares it a sync master
+Plays attached sound looping at volume (0.0 - 1.0), declares it a sync master
 	</string>
 	<string name="LSLTipText_llLoopSoundSlave">
 llLoopSoundSlave(string sound, float volume)
-plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master
+Plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master
 	</string>
 	<string name="LSLTipText_llPlaySoundSlave">
 llPlaySoundSlave(string sound, float volume)
-plays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master
+Plays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master
 	</string>
 	<string name="LSLTipText_llTriggerSound">
 llTriggerSound(string sound, float volume)
-plays sound at volume (0.0 - 1.0), centered at but not attached to object
+Plays sound at volume (0.0 - 1.0), centered at but not attached to object
 	</string>
 	<string name="LSLTipText_llStopSound">
 llStopSound()
@@ -677,143 +679,143 @@ Stops currently attached sound
 	</string>
 	<string name="LSLTipText_llPreloadSound">
 llPreloadSound(string sound)
-preloads a sound on viewers within range
+Preloads a sound on viewers within range
 	</string>
 	<string name="LSLTipText_llGetSubString">
 string llGetSubString(string src, integer start, integer end)
-returns the indicated substring
+Returns the indicated substring
 	</string>
 	<string name="LSLTipText_llDeleteSubString">
 string llDeleteSubString(string src, integer start, integer end)
-removes the indicated substring and returns the result
+Removes the indicated substring and returns the result
 	</string>
 	<string name="LSLTipText_llInsertString">
 string llInsertString(string dst, integer position, string src)
-inserts src into dst at position and returns the result
+Returns a destination string dst with the string src inserted starting at position pos
 	</string>
 	<string name="LSLTipText_llToUpper">
 string llToUpper(string src)
-convert src to all upper case and returns the result
+Returns a string that is src with all upper-case characters
 	</string>
 	<string name="LSLTipText_llToLower">
 string llToLower(string src)
-convert src to all lower case and returns the result
+Returns a string that is src with all lower-case characters
 	</string>
 	<string name="LSLTipText_llGiveMoney">
 llGiveMoney(key destination, integer amount)
-transfer amount of money from script owner to destination
+Transfers amount of L$ from script owner to destination
 	</string>
 	<string name="LSLTipText_llMakeExplosion">
 llMakeExplosion(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make a round explosion of particles
+Makes a round explosion of particles
 	</string>
 	<string name="LSLTipText_llMakeFountain">
 llMakeFountain(integer particles, float scale, float vel, float lifetime, float arc, integer bounce, string texture, vector offset, float bounce_offset)
-Make a fountain of particles
+Makes a fountain of particles
 	</string>
 	<string name="LSLTipText_llMakeSmoke">
 llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make smoke like particles
+Makes smoke like particles
 	</string>
 	<string name="LSLTipText_llMakeFire">
 llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
-Make fire like particles
+Makes fire like particles
 	</string>
 	<string name="LSLTipText_llRezObject">
 llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)
-Instanciate owners inventory object at pos with velocity vel and rotation rot with start parameter param
+Instantiates owner&apos;s inventory object at pos with velocity vel and rotation rot with start parameter param
 	</string>
 	<string name="LSLTipText_llLookAt">
-llLookAt(vector target, F32 strength, F32 damping)
-Cause object name to point it&apos;s forward axis towards target
+llLookAt(vector target, float strength, float damping)
+Causes object to point its up axis (positive z) towards target, while keeping its forward axis (positive x) below the horizon
 	</string>
 	<string name="LSLTipText_llStopLookAt">
 llStopLookAt()
-Stop causing object name to point at a target
+Stops causing object to point at a target
 	</string>
 	<string name="LSLTipText_llSetTimerEvent">
 llSetTimerEvent(float sec)
-Cause the timer event to be triggered every sec seconds
+Causes the timer event to be triggered a maximum of once every sec seconds
 	</string>
 	<string name="LSLTipText_llSleep">
 llSleep(float sec)
-Put script to sleep for sec seconds
+Puts the script to sleep for sec seconds
 	</string>
 	<string name="LSLTipText_llGetMass">
 float llGetMass()
-Get the mass of task name that script is attached to
+Returns the mass of object that the script is attached to
 	</string>
 	<string name="LSLTipText_llCollisionFilter">
 llCollisionFilter(string name, key id, integer accept)
-if accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id
+Sets the collision filter, exclusively or inclusively. If accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id
 	</string>
 	<string name="LSLTipText_llTakeControls">
 llTakeControls(integer controls, integer accept, integer pass_on)
-Take controls from agent task has permissions for.  If (accept == (controls &amp; input)), send input to task.  If pass_on send to agent also.
+Allows for intercepting keyboard and mouse clicks from the agent the script has permissions for
 	</string>
 	<string name="LSLTipText_llReleaseControls">
 llReleaseControls()
-Stop taking inputs
+Stops taking inputs that were taken with llTakeControls
 	</string>
 	<string name="LSLTipText_llAttachToAvatar">
-llAttachToAvatar(integer attachment)
-Attach to avatar task has permissions for at point attachment
+llAttachToAvatar(integer attach_point)
+Attaches the object to the avatar who has granted permission to the script
 	</string>
 	<string name="LSLTipText_llDetachFromAvatar">
 llDetachFromAvatar()
-Drop off of avatar
+Detaches object from avatar
 	</string>
 	<string name="LSLTipText_llTakeCamera">
 llTakeCamera(key avatar)
-Move avatar&apos;s viewpoint to task
+Moves avatar&apos;s viewpoint to task
 	</string>
 	<string name="LSLTipText_llReleaseCamera">
 llReleaseCamera(key avatar)
-Return camera to agent
+Returns camera to agent avatar
 	</string>
 	<string name="LSLTipText_llGetOwner">
 key llGetOwner()
-Returns the owner of the task
+Returns the object owner&apos;s UUID
 	</string>
 	<string name="LSLTipText_llInstantMessage">
 llInstantMessage(key user, string message)
-IMs message to the user
+Sends the specified string as an Instant Message to the user
 	</string>
 	<string name="LSLTipText_llEmail">
 llEmail(string address, string subject, string message)
-Sends email to address with subject and message
+Sends an email to address with the subject and message
 	</string>
 	<string name="LSLTipText_llGetNextEmail">
 llGetNextEmail(string address, string subject)
-Get the next waiting email with appropriate address and/or subject (if blank they are ignored)
+Gets the next waiting email that comes from address, with specified subject
 	</string>
 	<string name="LSLTipText_llGetKey">
 key llGetKey()
-Get the key for the task the script is attached to
+Returns the key of the prim the script is attached to
 	</string>
 	<string name="LSLTipText_llSetBuoyancy">
 llSetBuoyancy(float buoyancy)
-Set the tasks buoyancy (0 is none, &lt; 1.0 sinks, 1.0 floats, > 1.0 rises)
+Sets the buoyancy of the task or object (0 is disabled, &lt; 1.0 sinks, 1.0 floats, &gt; 1.0 rises)
 	</string>
 	<string name="LSLTipText_llSetHoverHeight">
 llSetHoverHeight(float height, integer water, float tau)
-Critically damps to a height (either above ground level or above the higher of land and water if water == TRUE)
+Critically damps to a height above the ground (or water) in tau seconds
 	</string>
 	<string name="LSLTipText_llStopHover">
 llStopHover()
-Stop hovering to a height
+Stops hovering to a height
 	</string>
 	<string name="LSLTipText_llMinEventDelay">
 llMinEventDelay(float delay)
-Set the minimum time between events being handled
+Sets the minimum time between events being handled
 	</string>
 	<string name="LSLTipText_llSoundPreload">
 llSoundPreload(string sound)
-preloads a sound on viewers within range
+Preloads a sound on viewers within range
 	</string>
 	<string name="LSLTipText_llRotLookAt">
-llRotLookAt(rotation target, F32 strength, F32 damping)
-Cause object name to point it&apos;s forward axis towards target
+llRotLookAt(rotation target, float strength, float damping)
+Causes object name to point its forward axis towards target
 	</string>
 	<string name="LSLTipText_llStringLength">
 integer llStringLength(string str)
@@ -821,84 +823,83 @@ Returns the length of string
 	</string>
 	<string name="LSLTipText_llStartAnimation">
 llStartAnimation(string anim)
-Start animation anim for agent that owns object
+Starts animation anim for agent that granted PERMISSION_TRIGGER_ANIMATION if the permission has not been revoked
 	</string>
 	<string name="LSLTipText_llStopAnimation">
 llStopAnimation(string anim)
-Stop animation anim for agent that owns object
+Stops animation anim for agent that granted permission
 	</string>
 	<string name="LSLTipText_llPointAt">
 llPointAt(vector pos)
-Make agent that owns object point at pos
+Makes agent that owns object point at pos
 	</string>
 	<string name="LSLTipText_llStopPointAt">
 llStopPointAt()
-Stop agent that owns object pointing
+Stops pointing agent that owns object
 	</string>
 	<string name="LSLTipText_llTargetOmega">
 llTargetOmega(vector axis, float spinrate, float gain)
-Attempt to spin at spinrate with strength gain
+Rotates the object around axis at spinrate with strength gain
 	</string>
 	<string name="LSLTipText_llGetStartParameter">
 integer llGetStartParameter()
-Get's the start paramter passed to llRezObject
+Returns an integer that is the script start/rez parameter
 	</string>
 	<string name="LSLTipText_llGodLikeRezObject">
 llGodLikeRezObject(key inventory, vector pos)
-rez directly off of a UUID if owner has dog-bit set
+Rezzes directly off of UUID if owner is in God Mode
 	</string>
 	<string name="LSLTipText_llRequestPermissions">
 llRequestPermissions(key agent, integer perm)
-ask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)
+Asks the agent for permission to run certain classes of functions
 	</string>
 	<string name="LSLTipText_llGetPermissionsKey">
 key llGetPermissionsKey()
-Return agent that permissions are enabled for.  NULL_KEY if not enabled
+Returns the key of the avatar that last granted permissions to the script
 	</string>
 	<string name="LSLTipText_llGetPermissions">
 integer llGetPermissions()
-return what permissions have been enabled
+Returns an integer bitfield with the permissions that have been granted
 	</string>
 	<string name="LSLTipText_llGetLinkNumber">
 integer llGetLinkNumber()
-Returns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, etc)
+Returns the link number of the prim containing the script (0 means not linked, 1 the prim is the root, 2 the prim is the first child, etc)
 	</string>
 	<string name="LSLTipText_llSetLinkColor">
 llSetLinkColor(integer linknumber, vector color, integer face)
-If a task exists in the link chain at linknumber, set face to color
+Sets face to color if a task exists in the link chain at linknumber
 	</string>
 	<string name="LSLTipText_llCreateLink">
 llCreateLink(key target, integer parent)
-Attempt to link task script is attached to and target (requires permission PERMISSION_CHANGE_LINKS be set). If parent == TRUE, task script is attached to is the root
+Attempts to link the script&apos;s object with the target (requires that PERMISSION_CHANGE_LINKS be granted). If parent == TRUE, then the script&apos;s object becomes the root
 	</string>
 	<string name="LSLTipText_llBreakLink">
 llBreakLink(integer linknum)
-Delinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)
+Delinks the prim with the given link number in a linked object set (requires that PERMISSION_CHANGE_LINKS be granted)
 	</string>
 	<string name="LSLTipText_llBreakAllLinks">
 llBreakAllLinks()
-Delinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)
+Delinks all prims in the link set (requires that PERMISSION_CHANGE_LINKS be granted)
 	</string>
 	<string name="LSLTipText_llGetLinkKey">
-key llGetLinkKey(integer linknum)
-Get the key of linknumber in link set
+key llGetLinkKey(integer linknumber)
+Returns the key of the linked prim linknumber
 	</string>
 	<string name="LSLTipText_llGetLinkName">
-string llGetLinkName(integer linknum)
-Get the name of linknumber in link set
+string llGetLinkName(integer linknumber)
+Returns the name of linknumber in a link set
 	</string>
 	<string name="LSLTipText_llGetInventoryNumber">
 integer llGetInventoryNumber(integer type)
-Get the number of items of a given type in the task's inventory.
-Valid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL
+Returns the number of items of a given type (INVENTORY_* flag) in the prim&apos;s inventory
 	</string>
 	<string name="LSLTipText_llGetInventoryName">
 string llGetInventoryName(integer type, integer number)
-Get the name of the inventory item number of type
+Returns the name of the inventory item number of a given type
 	</string>
 	<string name="LSLTipText_llSetScriptState">
 llSetScriptState(string name, integer run)
-Control the state of a script name.
+Sets the running state of the specified script
 	</string>
 	<string name="LSLTipText_llGetEnergy">
 float llGetEnergy()
@@ -906,56 +907,55 @@ Returns how much energy is in the object as a percentage of maximum
 	</string>
 	<string name="LSLTipText_llGiveInventory">
 llGiveInventory(key destination, string inventory)
-Give inventory to destination
+Gives inventory to destination
 	</string>
 	<string name="LSLTipText_llRemoveInventory">
-llRemoveInventory(string inventory)
-Remove the named inventory item
+llRemoveInventory(string item)
+Removes the named inventory item
 	</string>
 	<string name="LSLTipText_llSetText">
 llSetText(string text, vector color, float alpha)
-Set text floating over object
+Displays text that hovers over the prim with specific color and translucency specified with alpha
 	</string>
 	<string name="LSLTipText_llWater">
-float llWater(vector v)
-returns the water height below the object position + v
+float llWater(vector offset)
+Returns the water height below the object position + offset
 	</string>
 	<string name="LSLTipText_llPassTouches">
 llPassTouches(integer pass)
-if pass == TRUE, touches are passed from children on to parents (default is FALSE)
+If pass == TRUE, touches are passed from children on to parents
 	</string>
 	<string name="LSLTipText_llRequestAgentData">
 key llRequestAgentData(key id, integer data)
-Requests data about agent id.  When data is available the dataserver event will be raised
+Requests data about agent id. When data is available the dataserver event will be raised.
 	</string>
 	<string name="LSLTipText_llRequestInventoryData">
 key llRequestInventoryData(string name)
-Requests data from object's inventory object.  When data is available the dataserver event will be raised
+Requests data from object&apos;s inventory object. When data is available the dataserver event will be raised.
 	</string>
 	<string name="LSLTipText_llSetDamage">
 llSetDamage(float damage)
-Sets the amount of damage that will be done to an object that this task hits.  Task will be killed.
+Sets the amount of damage that will be done when this object hits an avatar.
 	</string>
 	<string name="LSLTipText_llTeleportAgentHome">
 llTeleportAgentHome(key id)
-Teleports agent on owner's land to agent's home location
+Teleports avatar on the owner&apos;s land to their home location without any warning
 	</string>
 	<string name="LSLTipText_llModifyLand">
-llModifyLand(integer action, integer size)
-Modify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)
-on size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)
+llModifyLand(integer action, integer brush)
+Modifies land using the specified action on the specified brush size of land
 	</string>
 	<string name="LSLTipText_llCollisionSound">
 llCollisionSound(string impact_sound, float impact_volume)
-Suppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)
+Suppresses default collision sounds, replaces default impact sounds with impact_sound at the volume impact_volume
 	</string>
 	<string name="LSLTipText_llCollisionSprite">
 llCollisionSprite(string impact_sprite)
-Suppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)
+Suppresses default collision sprites, replaces default impact sprite with impact_sprite (use an empty string to just suppress)
 	</string>
 	<string name="LSLTipText_llGetAnimation">
 string llGetAnimation(key id)
-Get the currently playing locomotion animation for avatar id
+Returns the name of the currently playing locomotion animation for avatar id
 	</string>
 	<string name="LSLTipText_llResetScript">
 llResetScript()
@@ -963,12 +963,7 @@ Resets the script
 	</string>
 	<string name="LSLTipText_llMessageLinked">
 llMessageLinked(integer linknum, integer num, string str, key id)
-Sends num, str, and id to members of the link set
-(LINK_ROOT sends to root task in a linked set,
-LINK_SET sends to all tasks,
-LINK_ALL_OTHERS to all other tasks,
-LINK_ALL_CHILDREN to all children,
-LINK_THIS to the task the script it is in)
+Allows scripts in the same object to communicate. Triggers a link_message event with the same parameters num, str, and id in all scripts in the prim(s) described by linknum.
 	</string>
 	<string name="LSLTipText_llPushObject">
 llPushObject(key id, vector impulse, vector ang_impulse, integer local)
@@ -976,19 +971,19 @@ Applies impulse and ang_impulse to object id
 	</string>
 	<string name="LSLTipText_llPassCollisions">
 llPassCollisions(integer pass)
-if pass == TRUE, collisions are passed from children on to parents (default is FALSE)
+If pass == TRUE, collisions are passed from children on to parents (default is FALSE)
 	</string>
 	<string name="LSLTipText_llGetScriptName">
-llGetScriptName()
-Returns the script name
+string llGetScriptName()
+Returns the name of the script that this function is used in
 	</string>
 	<string name="LSLTipText_llGetNumberOfSides">
 integer llGetNumberOfSides()
-Returns the number of sides
+Returns the number of faces (or sides) of the prim
 	</string>
 	<string name="LSLTipText_llAxisAngle2Rot">
 rotation llAxisAngle2Rot(vector axis, float angle)
-Returns the rotation generated angle about axis
+Returns the rotation that is a generated angle about axis
 	</string>
 	<string name="LSLTipText_llRot2Axis">
 vector llRot2Axis(rotation rot)
@@ -1012,19 +1007,19 @@ Returns angle between rotation a and b
 	</string>
 	<string name="LSLTipText_llGetInventoryKey">
 key llGetInventoryKey(string name)
-Returns the key of the inventory name
+Returns the key that is the UUID of the inventory name
 	</string>
 	<string name="LSLTipText_llAllowInventoryDrop">
 llAllowInventoryDrop(integer add)
-If add == TRUE, users without permissions can still drop inventory items onto task
+If add == TRUE, users without modify permissions can still drop inventory items onto a prim
 	</string>
 	<string name="LSLTipText_llGetSunDirection">
 vector llGetSunDirection()
-Returns the sun direction on the simulator
+Returns a normalized vector of the direction of the sun in the region
 	</string>
 	<string name="LSLTipText_llGetTextureOffset">
-vector llGetTextureOffset(integer side)
-Returns the texture offset of side in the x and y components of a vector
+vector llGetTextureOffset(integer face)
+Returns the texture offset of face in the x and y components of a vector
 	</string>
 	<string name="LSLTipText_llGetTextureScale">
 vector llGetTextureScale(integer side)
@@ -1036,55 +1031,57 @@ Returns the texture rotation of side
 	</string>
 	<string name="LSLTipText_llSubStringIndex">
 integer llSubStringIndex(string source, string pattern)
-Finds index in source where pattern first appears (returns -1 if not found)
+Returns an integer that is the index in source where pattern first appears.
+(Returns -1 if not found)
 	</string>
 	<string name="LSLTipText_llGetOwnerKey">
 key llGetOwnerKey(key id)
-Find the owner of id
+Returns the owner of object id
 	</string>
 	<string name="LSLTipText_llGetCenterOfMass">
 vector llGetCenterOfMass()
-Get the object's center of mass
+Returns the prim&apos;s center of mass (unless called from the root prim, where it returns the object&apos;s center of mass)
 	</string>
 	<string name="LSLTipText_llListSort">
 list llListSort(list src, integer stride, integer ascending)
-Sort the list into blocks of stride in ascending order if ascending == TRUE.  Note that sort only works between same types.
+Sorts the list into blocks of stride, in ascending order if ascending == TRUE.
+The sort order is affected by type.
 	</string>
 	<string name="LSLTipText_llGetListLength">
 integer llGetListLength(list src)
-Get the number of elements in the list
+Returns the number of elements in the list
 	</string>
 	<string name="LSLTipText_llList2Integer">
 integer llList2Integer(list src, integer index)
-Copy the integer at index in the list
+Copies the integer at index in the list
 	</string>
 	<string name="LSLTipText_llList2Float">
 float llList2Float(list src, integer index)
-Copy the float at index in the list
+Copies the float at index in the list
 	</string>
 	<string name="LSLTipText_llList2String">
 string llList2String(list src, integer index)
-Copy the string at index in the list
+Copies the string at index in the list
 	</string>
 	<string name="LSLTipText_llList2Key">
 key llList2Key(list src, integer index)
-Copy the key at index in the list
+Copies the key at index in the list
 	</string>
 	<string name="LSLTipText_llList2Vector">
 vector llList2Vector(list src, integer index)
-Copy the vector at index in the list
+Copies the vector at index in the list
 	</string>
 	<string name="LSLTipText_llList2Rot">
 rotation llList2Rot(list src, integer index)
-Copy the rotation at index in the list
+Copies the rotation at index in the list
 	</string>
 	<string name="LSLTipText_llList2List">
 list llList2List(list src, integer start, integer end)
-Copy the slice of the list from start to end
+Copies the slice of the list from start to end
 	</string>
 	<string name="LSLTipText_llDeleteSubList">
 list llDeleteSubList(list src, integer start, integer end)
-Remove the slice from the list and return the remainder
+Removes the slice from start to end and returns the remainder of the list
 	</string>
 	<string name="LSLTipText_llGetListEntryType">
 integer llGetListEntryType(list src, integer index)
@@ -1093,11 +1090,11 @@ Returns the type of the index entry in the list
 	</string>
 	<string name="LSLTipText_llList2CSV">
 string llList2CSV(list src)
-Create a string of comma separated values from list
+Creates a string of comma separated values from list
 	</string>
 	<string name="LSLTipText_llCSV2List">
 list llCSV2List(string src)
-Create a list from a string of comma separated values
+Creates a list from a string of comma separated values
 	</string>
 	<string name="LSLTipText_llListRandomize">
 list llListRandomize(list src, integer stride)
@@ -1105,80 +1102,83 @@ Returns a randomized list of blocks of size stride
 	</string>
 	<string name="LSLTipText_llList2ListStrided">
 list llList2ListStrided(list src, integer start, integer end, integer stride)
-Copy the strided slice of the list from start to end
+Copies the strided slice of the list from start to end
 	</string>
 	<string name="LSLTipText_llGetRegionCorner">
 vector llGetRegionCorner()
-Returns a vector with the south west corner x,y position of the region the object is in
+Returns a vector in meters that is the global location of the south-west corner of the region which the object is in
 	</string>
 	<string name="LSLTipText_llListInsertList">
 list llListInsertList(list dest, list src, integer start)
-Inserts src into dest at position start
+Returns a list that contains all the elements from dest but with the elements from src inserted at position start
 	</string>
 	<string name="LSLTipText_llListFindList">
 integer llListFindList(list src, list test)
-Returns the start of the first instance of test in src, -1 if not found
+Returns the index of the first instance of test in src.
+(Returns -1 if not found)
 	</string>
 	<string name="LSLTipText_llGetObjectName">
 string llGetObjectName()
-Returns the name of the object script is attached to
+Returns the name of the prim which the script is attached to
 	</string>
 	<string name="LSLTipText_llSetObjectName">
 llSetObjectName(string name)
-Sets the objects name
+Sets the prim&apos;s name to the name parameter
 	</string>
 	<string name="LSLTipText_llGetDate">
 string llGetDate()
-Gets the date as YYYY-MM-DD
+Returns the current date in the UTC time zone in the format YYYY-MM-DD
 	</string>
 	<string name="LSLTipText_llEdgeOfWorld">
 integer llEdgeOfWorld(vector pos, vector dir)
-Checks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)
+Checks to see whether the border hit by dir from pos is the edge of the world (has no neighboring region)
 	</string>
 	<string name="LSLTipText_llGetAgentInfo">
 integer llGetAgentInfo(key id)
-Gets information about agent ID.
-Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING, AGENT_IN_AIR and/or AGENT_AUTOPILOT.
+Returns an integer bitfield containing the agent information about id.
+Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR.
 	</string>
 	<string name="LSLTipText_llAdjustSoundVolume">
 llAdjustSoundVolume(float volume)
-adjusts volume of attached sound (0.0 - 1.0)
+Adjusts volume of attached sound (0.0 - 1.0)
 	</string>
 	<string name="LSLTipText_llSetSoundQueueing">
 llSetSoundQueueing(integer queue)
-determines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)
+Sets whether attached sounds wait for the current sound to finish (If queue == TRUE then queuing is enabled, if FALSE queuing is disabled [default])
 	</string>
 	<string name="LSLTipText_llSetSoundRadius">
 llSetSoundRadius(float radius)
-establishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)
+Establishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)
 	</string>
 	<string name="LSLTipText_llKey2Name">
 string llKey2Name(key id)
-Returns the name of the object key, iff the object is in the current simulator, otherwise the empty string
+Returns the name of the prim or avatar specified by id.
+(The id must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.)
 	</string>
 	<string name="LSLTipText_llSetTextureAnim">
 llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)
-Animate the texture on the specified face/faces
+Animates the texture on the specified face/faces
 	</string>
 	<string name="LSLTipText_llTriggerSoundLimited">
-llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)
-plays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to AABB defined by vectors top-north-east and bottom-south-west
+llTriggerSoundLimited(string sound, float volume, vector top_north_east, vector bottom_south_west)
+Plays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to the box defined by vectors top_north_east and bottom_south_west
 	</string>
 	<string name="LSLTipText_llEjectFromLand">
-llEjectFromLand(key pest)
-Ejects pest from land that you own
+llEjectFromLand(key avatar)
+Ejects avatar from the parcel
 	</string>
 	<string name="LSLTipText_llParseString2List">
 list llParseString2List(string src, list separators, list spacers)
-Breaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each)
+Breaks src into a list, discarding separators, keeping spacers
+(separators and spacers must be lists of strings, maximum of 8 each)
 	</string>
 	<string name="LSLTipText_llOverMyLand">
 integer llOverMyLand(key id)
-Returns TRUE if id is over land owner of object owns, FALSE otherwise
+Returns TRUE if id is over land owned by the script owner, otherwise FALSE
 	</string>
 	<string name="LSLTipText_llGetLandOwnerAt">
 key llGetLandOwnerAt(vector pos)
-Returns the key of the land owner, NULL_KEY if public
+Returns the key of the land owner, returns NULL_KEY if public
 	</string>
 	<string name="LSLTipText_llGetNotecardLine">
 key llGetNotecardLine(string name, integer line)
@@ -1186,131 +1186,130 @@ Returns line line of notecard name via the dataserver event
 	</string>
 	<string name="LSLTipText_llGetAgentSize">
 vector llGetAgentSize(key id)
-If the agent is in the same sim as the object, returns the size of the avatar
+If the avatar is in the same region, returns the size of the bounding box of the requested avatar by id, otherwise returns ZERO_VECTOR
 	</string>
 	<string name="LSLTipText_llSameGroup">
 integer llSameGroup(key id)
-Returns TRUE if ID is in the same sim and has the same active group, otherwise FALSE
+Returns TRUE if avatar id is in the same region and has the same active group, otherwise FALSE
 	</string>
 	<string name="LSLTipText_llUnSit">
 key llUnSit(key id)
-If agent identified by id is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up
+If avatar identified by id is sitting on the object the script is attached to or is over land owned by the object&apos;s owner, the avatar is forced to stand up
 	</string>
 	<string name="LSLTipText_llGroundSlope">
-vector llGroundSlope(vector v)
-returns the ground slope below the object position + v
+vector llGroundSlope(vector offset)
+Returns the ground slope below the object position + offset
 	</string>
 	<string name="LSLTipText_llGroundNormal">
-vector llGroundNormal(vector v)
-returns the ground normal below the object position + v
+vector llGroundNormal(vector offset)
+Returns the ground normal below the object position + offset
 	</string>
 	<string name="LSLTipText_llGroundContour">
-vector llGroundCountour(vector v)
-returns the ground contour below the object position + v
+vector llGroundCountour(vector offset)
+Returns the ground contour direction below the object position + offset
 	</string>
 	<string name="LSLTipText_llGetAttached">
 integer llGetAttached()
-returns the object attachment point or 0 if not attached
+Returns the object&apos;s attachment point, or 0 if not attached
 	</string>
 	<string name="LSLTipText_llGetFreeMemory">
 integer llGetFreeMemory()
-returns the available heap space for the current script
+Returns the number of free bytes of memory the script can use
 	</string>
 	<string name="LSLTipText_llGetRegionName">
 string llGetRegionName()
-returns the current region name
+Returns the current region name
 	</string>
 	<string name="LSLTipText_llGetRegionTimeDilation">
 float llGetRegionTimeDilation()
-returns the current time dilation as a float between 0 and 1
+Returns the current time dilation as a float between 0.0 (full dilation) and 1.0 (no dilation)
 	</string>
 	<string name="LSLTipText_llGetRegionFPS">
 float llGetRegionFPS()
-returns the mean region frames per second
+Returns the mean region frames per second
 	</string>
 	<string name="LSLTipText_llParticleSystem">
 llParticleSystem(list rules)
-Creates a particle system based on rules.  Empty list removes particle system from object.
+Creates a particle system based on rules.  An empty list removes the particle system.
 List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]
 	</string>
 	<string name="LSLTipText_llGroundRepel">
 llGroundRepel(float height, integer water, float tau)
-Critically damps to height if within height*0.5 of level (either above ground level or above the higher of land and water if water == TRUE)
+Critically damps to height if within height*0.5 of level (either above ground level, or above the higher of land and water if water == TRUE)
 	</string>
 	<string name="LSLTipText_llGiveInventoryList">
-llGiveInventoryList(key destination, string category, list inventory)
-Give inventory to destination in a new category
+llGiveInventoryList(key target, string folder, list inventory)
+Gives inventory items to target, creating a new folder to put them in
 	</string>
 	<string name="LSLTipText_llSetVehicleType">
 llSetVehicleType(integer type)
-sets vehicle to one of the default types
+Sets the vehicle to one of the default types
 	</string>
 	<string name="LSLTipText_llSetVehicleFloatParam">
 llSetVehicleFloatParam(integer param, float value)
-sets the specified vehicle float parameter
+Sets the specified vehicle float parameter
 	</string>
 	<string name="LSLTipText_llSetVehicleVectorParam">
 llSetVehicleVectorParam(integer param, vector vec)
-sets the specified vehicle vector parameter
+Sets the specified vehicle vector parameter
 	</string>
 	<string name="LSLTipText_llSetVehicleRotationParam">
 llSetVehicleVectorParam(integer param, rotation rot)
-sets the specified vehicle rotation parameter
+Sets the specified vehicle rotation parameter
 	</string>
 	<string name="LSLTipText_llSetVehicleFlags">
 llSetVehicleFlags(integer flags)
-sets the enabled bits in 'flags'
+Sets the enabled bits in &apos;flags&apos;
 	</string>
 	<string name="LSLTipText_llRemoveVehicleFlags">
 llRemoveVehicleFlags(integer flags)
-removes the enabled bits in 'flags'
+Removes the enabled bits in &apos;flags&apos;
 	</string>
 	<string name="LSLTipText_llSitTarget">
 llSitTarget(vector offset, rotation rot)
-Set the sit location for this object (if offset == &lt;0,0,0&gt; clear it)
+Sets the sit location for the prim.  If offset == &lt;0,0,0&gt; then the sit target is removed.
 	</string>
 	<string name="LSLTipText_llAvatarOnSitTarget">
 key llAvatarOnSitTarget()
-If an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise
+If an avatar is seated on the sit target, returns the avatar&apos;s key, otherwise NULL_KEY
 	</string>
 	<string name="LSLTipText_llAddToLandPassList">
 llAddToLandPassList(key avatar, float hours)
-Add avatar to the land pass list for hours
+Adds avatar to the land pass list for hours, or indefinitely if hours is 0
 	</string>
 	<string name="LSLTipText_llSetTouchText">
 llSetTouchText(string text)
-Displays text in pie menu that acts as a touch
+Displays text rather than the default &apos;Touch&apos; in the pie menu
 	</string>
 	<string name="LSLTipText_llSetSitText">
 llSetSitText(string text)
-Displays text rather than sit in pie menu
+Displays text rather than the default &apos;Sit Here&apos; in the pie menu
 	</string>
 	<string name="LSLTipText_llSetCameraEyeOffset">
 llSetCameraEyeOffset(vector offset)
-Sets the camera eye offset used in this object if an avatar sits on it
+Sets the camera eye offset for avatars that sit on the object
 	</string>
 	<string name="LSLTipText_llSetCameraAtOffset">
 llSetCameraAtOffset(vector offset)
-Sets the camera at offset used in this object if an avatar sits on it
+Sets the point the camera is looking at to offset for avatars that sit on the object
 	</string>
 	<string name="LSLTipText_llDumpList2String">
 string llDumpList2String(list src, string separator)
-Write the list out in a single string using separator between values
+Returns the list in a single string, using separator between the entries
 	</string>
 	<string name="LSLTipText_llScriptDanger">
 integer llScriptDanger(vector pos)
-Returns true if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts
+Returns TRUE if pos is over public land, sandbox land, land that doesn&apos;t allow everyone to edit and build, or land that doesn&apos;t allow outside scripts
 	</string>
 	<string name="LSLTipText_llDialog">
 llDialog(key avatar, string message, list buttons, integer chat_channel
-Shows a dialog box on the avatar's screen with the message.
-Up to 12 strings in the list form buttons.
-If a button is clicked, the name is chatted on chat_channel.
+Shows a dialog box on the avatar&apos;s screen with a message and up to 12 buttons.
+If a button is pressed, the avatar says the text of the button label on chat_channel.
 	</string>
 	<string name="LSLTipText_llVolumeDetect">
 llVolumeDetect(integer detect)
-If detect = TRUE, object becomes phantom but triggers collision_start and collision_end events when other objects start and stop interpenetrating.
-Must be applied to the root object.
+If detect = TRUE, object works much like Phantom, but triggers collision_start and collision_end events when other objects start and stop interpenetrating.
+Must be applied to the root prim.
 	</string>
 	<string name="LSLTipText_llResetOtherScript">
 llResetOtherScript(string name)
@@ -1318,110 +1317,107 @@ Resets script name
 	</string>
 	<string name="LSLTipText_llGetScriptState">
 integer llGetScriptState(string name)
-Resets TRUE if script name is running
+Returns TRUE if the script name is running
 	</string>
 	<string name="LSLTipText_llRemoteLoadScript">
-Deprecated.  Please use llRemoteLoadScriptPin instead.
+DEPRECATED!  Please use llRemoteLoadScriptPin instead.
 	</string>
 	<string name="LSLTipText_llSetRemoteScriptAccessPin">
 llSetRemoteScriptAccessPin(integer pin)
-If pin is set to a non-zero number, the task will accept remote script loads via llRemoteLoadScriptPin if it passes in the correct pin.
-Othersise, llRemoteLoadScriptPin is ignored.
+If pin is set to a non-zero number, allows a prim to have scripts remotely loaded via llRemoteLoadScriptPin when it passes in the correct pin. Otherwise, llRemoteLoadScriptPin is ignored.
 	</string>
 	<string name="LSLTipText_llRemoteLoadScriptPin">
 llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)
-If the owner of the object this script is attached can modify target, 
-they are in the same region, and the matching pin is used,
-copy script name onto target,
-if running == TRUE, start the script with param.
+Copies script name onto target, if the owner of this scripted object can modify target and is in the same region, and the matching pin is used.
+If running == TRUE, starts the script with start_param
 	</string>
 	<string name="LSLTipText_llOpenRemoteDataChannel">
 llOpenRemoteDataChannel()
-Creates a channel to listen for XML-RPC calls.  Will trigger a remote_data event with channel id once it is available.
+Creates a channel to listen for XML-RPC calls, and will trigger a remote_data event with channel id once it is available
 	</string>
 	<string name="LSLTipText_llSendRemoteData">
 key llSendRemoteData(key channel, string dest, integer idata, string sdata)
-Send an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.
-A message identifier key is returned.
-An XML-RPC reply will trigger a remote_data event and reference the message id.
-The message_id is returned.
+Sends an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.
+Returns a key that is the message_id for the resulting remote_data events.
 	</string>
 	<string name="LSLTipText_llRemoteDataReply">
 llRemoteDataReply(key channel, key message_id, string sdata, integer idata)
-Send an XML-RPC reply to message_id on channel with payload of string sdata and integer idata
+Sends an XML-RPC reply to message_id on channel with payload of string sdata and integer idata
 	</string>
 	<string name="LSLTipText_llCloseRemoteDataChannel">
 llCloseRemoteDataChannel(key channel)
-Closes XML-RPC channel.
+Closes XML-RPC channel
 	</string>
 	<string name="LSLTipText_llMD5String">
 string llMD5String(string src, integer nonce)
-Performs a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce.  Returns a 32 character hex string.
+Returns a string of 32 hex characters that is a RSA Data Security, Inc. MD5 Message-Digest Algorithm of src with nonce
 	</string>
 	<string name="LSLTipText_llSetPrimitiveParams">
 llSetPrimitiveParams(list rules)
-Set primitive parameters based on rules.
+Sets the prim&apos;s parameters according to rules
 	</string>
 	<string name="LSLTipText_llStringToBase64">
 string llStringToBase64(string str)
-Converts a string to the Base 64 representation of the string.
+Converts a string to the Base64 representation of the string
 	</string>
 	<string name="LSLTipText_llBase64ToString">
 string llBase64ToString(string str)
-Converts a Base 64 string to a conventional string.  If the conversion creates any unprintable characters, they are converted to spaces.
+Converts a Base64 string to a conventional string.
+If the conversion creates any unprintable characters, they are converted to spaces.
 	</string>
 	<string name="LSLTipText_llXorBase64Strings">
 string llXorBase64Strings(string s1, string s2)
-DEPRECATED!  Please use llXorBase64StringsCorrect instead!!  Incorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string.  s2 repeats if it is shorter than s1.  Retained for backwards compatability.
+DEPRECATED!  Please use llXorBase64StringsCorrect instead.
+Incorrectly performs an exclusive or on two Base64 strings and returns a Base64 string.  s2 repeats if it is shorter than s1.  Retained for backwards compatability.
 	</string>
 	<string name="LSLTipText_llRemoteDataSetRegion">
 llRemoteDataSetRegion()
-If an object using remote data channels changes regions, you must call this function to reregister the remote data channels.
-You do not need to make this call if you don't change regions.
+DEPRECATED!  Please use llOpenRemoteDataChannel instead.
+If an object using remote data channels changes regions, you must call this function to reregister the remote data channels. This call is not needed if the prim does not change regions.
 	</string>
 	<string name="LSLTipText_llLog10">
 float llLog10(float val)
-Returns the base 10 log of val if val &gt; 0, otherwise returns 0.
+Returns the base 10 logarithm of val.  Returns zero if val &lt;= 0.
 	</string>
 	<string name="LSLTipText_llLog">
 float llLog(float val)
-Returns the base e log of val if val &gt; 0, otherwise returns 0.
+Returns the natural logarithm of val.  Returns zero if val &lt;= 0.
 	</string>
 	<string name="LSLTipText_llGetAnimationList">
 list llGetAnimationList(key id)
-Gets a list of all playing animations for avatar id
+Returns a list of keys of playing animations for avatar described by id
 	</string>
 	<string name="LSLTipText_llSetParcelMusicURL">
 llSetParcelMusicURL(string url)
-Sets the streaming audio URL for the parcel object is on
+Sets the streaming audio URL for the parcel which the object is on
 	</string>
 	<string name="LSLTipText_llGetRootPosition">
 vector llGetRootPosition()
-Gets the global position of the root object of the object script is attached to
+Returns the position (in region coordinates) of the root prim of the object which the script is attached to
 	</string>
 	<string name="LSLTipText_llGetRootRotation">
 rotation llGetRootRotation()
-Gets the global rotation of the root object of the object script is attached to
+Returns the rotation (relative to the region) of the root prim of the object which the script is attached to
 	</string>
 	<string name="LSLTipText_llGetObjectDesc">
 string llGetObjectDesc()
-Returns the description of the object the script is attached to
+Returns the description of the prim the script is attached to
 	</string>
 	<string name="LSLTipText_llSetObjectDesc">
 llSetObjectDesc(string name)
-Sets the object's description
+Sets the prim&apos;s description
 	</string>
 	<string name="LSLTipText_llGetCreator">
 key llGetCreator()
-Returns the creator of the object
+Returns a key for the creator of the prim
 	</string>
 	<string name="LSLTipText_llGetTimestamp">
 string llGetTimestamp()
-Gets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ
+Returns the timestamp in the UTC time zone in the format: YYYY-MM-DDThh:mm:ss.ff..fZ
 	</string>
 	<string name="LSLTipText_llSetLinkAlpha">
 llSetLinkAlpha(integer linknumber, float alpha, integer face)
-If a prim exists in the link chain at linknumber, set face to alpha
+If a prim exists in the link chain at linknumber, sets face to alpha
 	</string>
 	<string name="LSLTipText_llGetNumberOfPrims">
 integer llGetNumberOfPrims()
@@ -1429,11 +1425,11 @@ Returns the number of prims in a link set the script is attached to
 	</string>
 	<string name="LSLTipText_llGetNumberOfNotecardLines">
 key llGetNumberOfNotecardLines(string name)
-Returns number of lines in notecard 'name' via the dataserver event (cast return value to integer)
+Returns number of lines in notecard name via the dataserver event (cast return value to integer)
 	</string>
 	<string name="LSLTipText_llGetBoundingBox">
 list llGetBoundingBox(key object)
-Returns the bounding box around an object (including any linked prims) relative to the root prim, in a list:  [ (vector) min_corner, (vector) max_corner ]
+Returns the bounding box around the object (including any linked prims) relative to its root prim, in a list in the format [ (vector) min_corner, (vector) max_corner ]
 	</string>
 	<string name="LSLTipText_llGetGeometricCenter">
 vector llGetGeometricCenter()
@@ -1441,142 +1437,143 @@ Returns the geometric center of the linked set the script is attached to.
 	</string>
 	<string name="LSLTipText_llGetPrimitiveParams">
 list llGetPrimitiveParams(list params)
-Gets primitive parameters specified in the params list.
+Returns the primitive parameters specified in the params list.
 	</string>
 	<string name="LSLTipText_llIntegerToBase64">
 string llIntegerToBase64(integer number)
-Big endian encode of of integer as a Base64 string.
+Returns a string that is a Base64 big endian encode of number
 	</string>
 	<string name="LSLTipText_llBase64ToInteger">
 integer llBase64ToInteger(string str)
-Big endian decode of a Base64 string into an integer.
+Returns an integer that is the str Base64 decoded as a big endian integer
 	</string>
 	<string name="LSLTipText_llGetGMTclock">
 float llGetGMTclock()
-Gets the time in seconds since midnight in GMT
+Returns the time in seconds since midnight GMT
 	</string>
 	<string name="LSLTipText_llGetSimulatorHostname">
 string llGetSimulatorHostname()
-Gets the hostname of the machine script is running on (same as string in viewer Help dialog)
+Returns the hostname of the machine which the script is running on (same as string in viewer Help dialog)
 	</string>
 	<string name="LSLTipText_llSetLocalRot">
 llSetLocalRot(rotation rot)
-sets the rotation of a child prim relative to the root prim
+Sets the rotation of a child prim relative to the root prim
 	</string>
 	<string name="LSLTipText_llParseStringKeepNulls">
 list llParseStringKeepNulls(string src, list separators, list spacers)
-Breaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each), keeping any null values generated.
+Breaks src into a list, discarding separators, keeping spacers, keeping any null values generated.
+(separators and spacers must be lists of strings, maximum of 8 each)
 	</string>
 	<string name="LSLTipText_llRezAtRoot">
 llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)
-Instantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.
-The last selected root object's location will be set to pos
+Instantiates owner&apos;s inventory object rotated to rot with its root at pos, moving at vel, using param as the start parameter
 	</string>
 	<string name="LSLTipText_llGetObjectPermMask">
 integer llGetObjectPermMask(integer mask)
-Returns the requested permission mask for the root object the task is attached to.
+Returns the requested permission mask for the root object the task is attached to
 	</string>
 	<string name="LSLTipText_llSetObjectPermMask">
 llSetObjectPermMask(integer mask, integer value)
-Sets the given permission mask to the new value on the root object the task is attached to.
+Sets the given permission mask to the new value on the root object the task is attached to
 	</string>
 	<string name="LSLTipText_llGetInventoryPermMask">
 integer llGetInventoryPermMask(string item, integer mask)
-Returns the requested permission mask for the inventory item.
+Returns the requested permission mask for the inventory item
 	</string>
 	<string name="LSLTipText_llSetInventoryPermMask">
 llSetInventoryPermMask(string item, integer mask, integer value)
-Sets the given permission mask to the new value on the inventory item.
+Sets the given permission mask to the new value on the inventory item
 	</string>
 	<string name="LSLTipText_llGetInventoryCreator">
 key llGetInventoryCreator(string item)
-Returns the key for the creator of the inventory item.
+Returns a key for the creator of the inventory item
 	</string>
 	<string name="LSLTipText_llOwnerSay">
 llOwnerSay(string msg)
-says msg to owner only (if owner in sim)
+Says msg to owner only.  (Owner must be in the same region.)
 	</string>
 	<string name="LSLTipText_llRequestSimulatorData">
 key llRequestSimulatorData(string simulator, integer data)
-Requests data about simulator.  When data is available the dataserver event will be raised
+Requests data about simulator.  When data is available the dataserver event will be raised.
 	</string>
 	<string name="LSLTipText_llForceMouselook">
 llForceMouselook(integer mouselook)
-If mouselook is TRUE any avatar that sits on this object is forced into mouselook mode
+If mouselook is TRUE, any avatar that sits upon the prim will be forced into mouselook mode
 	</string>
 	<string name="LSLTipText_llGetObjectMass">
 float llGetObjectMass(key id)
-Get the mass of the object with key id
+Returns the mass of the avatar or object in the region
 	</string>
 	<string name="LSLTipText_llListReplaceList">
 list llListReplaceList(list dest, list src, integer start, integer end)
-Replaces start through end of dest with src.
+Returns a list that is dest with start through end removed and src inserted at start
 	</string>
 	<string name="LSLTipText_llLoadURL">
-llLoadURL(key avatar_id, string message, string url)
-Shows dialog to avatar avatar_id offering to load web page at URL.  If user clicks yes, launches their web browser.
+llLoadURL(key avatar, string message, string url)
+Shows a dialog to avatar offering to load the web page at url with a message.
+If user clicks yes, launches the page in their web browser.
 	</string>
 	<string name="LSLTipText_llParcelMediaCommandList">
 llParcelMediaCommandList(list command)
-Sends a list of commands, some with arguments, to a parcel.
+Sends a list of commands, some with arguments, to a parcel to control the playback of movies and other media
 	</string>
 	<string name="LSLTipText_llParcelMediaQuery">
 list llParcelMediaQuery(list query)
-Sends a list of queries, returns a list of results.
+Returns a list containing results of the sent query
 	</string>
 	<string name="LSLTipText_llModPow">
 integer llModPow(integer a, integer b, integer c)
-Returns a raised to the b power, mod c. ( (a**b)%c ).  b is capped at 0xFFFF (16 bits).
+Returns a raised to the b power, mod c. ( (a**b)%c )
+b is capped at 0xFFFF (16 bits).
 	</string>
 	<string name="LSLTipText_llGetInventoryType">
 integer llGetInventoryType(string name)
-Returns the type of the inventory name
+Returns the type of the inventory item name
 	</string>
 	<string name="LSLTipText_llSetPayPrice">
 llSetPayPrice(integer price, list quick_pay_buttons)
-Sets the default amount when someone chooses to pay this object.
+Sets the default amount on the dialog that appears when someone chooses to pay this prim
 	</string>
 	<string name="LSLTipText_llGetCameraPos">
 vector llGetCameraPos()
-Gets current camera position for agent task has permissions for.
+Returns the current camera position for the agent the task has permissions for
 	</string>
 	<string name="LSLTipText_llGetCameraRot">
 rotation llGetCameraRot()
-Gets current camera orientation for agent task has permissions for.
+Returns the current camera orientation for the agent the task has permissions for
 	</string>
 	<string name="LSLTipText_llSetPrimURL">
 llSetPrimURL(string url)
-Updates the URL for the web page shown on the sides of the object.
+Updates the URL for the web page shown on the sides of the object
 	</string>
 	<string name="LSLTipText_llRefreshPrimURL">
 llRefreshPrimURL()
-Reloads the web page shown on the sides of the object.
+Reloads the web page shown on the sides of the object
 	</string>
 	<string name="LSLTipText_llEscapeURL">
 string llEscapeURL(string url)
-Returns and escaped/encoded version of url, replacing spaces with %20 etc.
+Returns an escaped/encoded version of url, replacing spaces with %20 etc.
 	</string>
 	<string name="LSLTipText_llUnescapeURL">
 string llUnescapeURL(string url)
-Returns and unescaped/unencoded version of url, replacing %20 with spaces etc.
+Returns an unescaped/ unencoded version of url, replacing %20 with spaces etc.
 	</string>
 	<string name="LSLTipText_llMapDestination">
 llMapDestination(string simname, vector pos, vector look_at)
-Opens world map centered on region with pos highlighted.
+Opens the World Map centered on the region simname with pos highlighted. (NOTE: look_at currently does nothing.)
 Only works for scripts attached to avatar, or during touch events.
-(NOTE: look_at currently does nothing)
 	</string>
 	<string name="LSLTipText_llAddToLandBanList">
 llAddToLandBanList(key avatar, float hours)
-Add avatar to the land ban list for hours
+Adds avatar to the land ban list for hours, or indefinitely if hours is 0
 	</string>
 	<string name="LSLTipText_llRemoveFromLandPassList">
 llRemoveFromLandPassList(key avatar)
-Remove avatar from the land pass list
+Removes avatar from the land pass list
 	</string>
 	<string name="LSLTipText_llRemoveFromLandBanList">
 llRemoveFromLandBanList(key avatar)
-Remove avatar from the land ban list
+Removes avatar from the land ban list
 	</string>
 	<string name="LSLTipText_llSetCameraParams">
 llSetCameraParams(list rules)
@@ -1585,158 +1582,174 @@ List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]
 	</string>
 	<string name="LSLTipText_llClearCameraParams">
 llClearCameraParams()
-Resets all camera parameters to default values and turns off scripted camera control.
+Resets all camera parameters to default values and turns off scripted camera control
 	</string>
 	<string name="LSLTipText_llListStatistics">
-float llListStatistics(integer operation, list l)
-Perform statistical aggregate functions on list l using LIST_STAT_* operations.
+float llListStatistics(integer operation, list src)
+Performs statistical aggregate functions on list src using LIST_STAT_* operations
 	</string>
 	<string name="LSLTipText_llGetUnixTime">
 integer llGetUnixTime()
-Get the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock.
+Returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock
 	</string>
 	<string name="LSLTipText_llGetParcelFlags">
 integer llGetParcelFlags(vector pos)
-Get the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.
+Returns a mask of the parcel flags (PARCEL_FLAG_*) for the parcel that includes the point pos
 	</string>
 	<string name="LSLTipText_llGetRegionFlags">
 integer llGetRegionFlags()
-Get the region flags (REGION_FLAG_*) for the region the object is in.
+Returns the region flags (REGION_FLAG_*) for the region the object is in
 	</string>
 	<string name="LSLTipText_llXorBase64StringsCorrect">
 string llXorBase64StringsCorrect(string s1, string s2)
-Correctly performs an exclusive or on two Base 64 strings and returns a Base 64 string.  s2 repeats if it is shorter than s1.
+Correctly performs an exclusive or on two Base64 strings and returns a Base64 string.
+s2 repeats if it is shorter than s1.
 	</string>
 	<string name="LSLTipText_llHTTPRequest">
 llHTTPRequest(string url, list parameters, string body)
-Send an HTTP request.
+Sends an HTTP request to the specified url with the body of the request and parameters
 	</string>
 	<string name="LSLTipText_llResetLandBanList">
 llResetLandBanList()
-Removes all residents from the land ban list.
+Removes all residents from the land ban list
 	</string>
 	<string name="LSLTipText_llResetLandPassList">
 llResetLandPassList()
-Removes all residents from the land access/pass list.
+Removes all residents from the land access/pass list
 	</string>
 	<string name="LSLTipText_llGetObjectPrimCount">
 integer llGetObjectPrimCount(key object_id)
-Returns the total number of prims for an object.
+Returns the total number of prims for an object in the region
 	</string>
 	<string name="LSLTipText_llGetParcelPrimOwners">
 list llGetParcelPrimOwners(vector pos)
-Returns a list of all residents who own objects on the parcel and the number of objects they own.
+Returns a list of all residents who own objects on the parcel at pos and with individual prim counts.
 Requires owner-like permissions for the parcel.
 	</string>
 	<string name="LSLTipText_llGetParcelPrimCount">
 integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)
-Gets the number of prims on the parcel of the given category.
-Categories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.
+Returns the number of prims on the parcel at pos of the given category.
+Categories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP
 	</string>
 	<string name="LSLTipText_llGetParcelMaxPrims">
 integer llGetParcelMaxPrims(vector pos, integer sim_wide)
-Gets the maximum number of prims allowed on the parcel at pos.
+Returns the maximum number of prims allowed on the parcel at pos
 	</string>
 	<string name="LSLTipText_llGetParcelDetails">
 list llGetParcelDetails(vector pos, list params)
-Gets the parcel details specified in params for the parcel at pos.
+Returns the parcel details specified in params for the parcel at pos.
 Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA
 	</string>
 	<string name="LSLTipText_llSetLinkPrimitiveParams">
 llSetLinkPrimitiveParams(integer linknumber, list rules)
-Set primitive parameters for linknumber based on rules.
+Sets primitive parameters for linknumber based on rules
 	</string>
 	<string name="LSLTipText_llSetLinkTexture">
-llSetLinkTexture(integer link_pos, string texture, integer face)
-Sets the texture of face for link_pos
+llSetLinkTexture(integer linknumber, string texture, integer face)
+Sets the texture of face for a task that exists in the link chain at linknumber
 	</string>
 	<string name="LSLTipText_llStringTrim">
 string llStringTrim(string src, integer trim_type)
-Trim leading and/or trailing spaces from a string.
-Uses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.
+Trims the leading and/or trailing white spaces from a string.
+trim_type can be STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.
 	</string>
 	<string name="LSLTipText_llRegionSay">
 llRegionSay(integer channel, string msg)
-broadcasts msg to entire region on channel (not 0.)
+Broadcasts msg on channel (not 0) that can be heard anywhere in the region by a script listening on channel
 	</string>
 	<string name="LSLTipText_llGetObjectDetails">
 list llGetObjectDetails(key id, list params)
-Gets the object details specified in params for the object with key id.
-Details are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.
+Returns the object details specified in params for the object with key id.
+Params are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR
 	</string>
 	<string name="LSLTipText_llSetClickAction">
 llSetClickAction(integer action)
-Sets the action performed when a prim is clicked upon.
+Sets the action performed when a prim is clicked upon
 	</string>
 	<string name="LSLTipText_llGetRegionAgentCount">
-int llGetRegionAgentCount()
-returns the number of agents in a region
+integer llGetRegionAgentCount()
+Returns the number of avatars in the region
 	</string>
 	<string name="LSLTipText_llTextBox">
 llTextBox(key avatar, string message, integer chat_channel
-Shows a dialog box on the avatar's screen with the message.
-A text box asks for input, and if entered the text is chatted on chat_channel.
+Shows a dialog box on the avatar&apos;s screen with the message.
+It contains a text box for input, and if entered that text is chatted on chat_channel.
 	</string>
 	<string name="LSLTipText_llGetAgentLanguage">
-string llGetAgentLanguage(key id)
-Gets the agents preferred language..
+string llGetAgentLanguage(key avatar)
+Returns the language code of the preferred interface language of the avatar
 	</string>
 	<string name="LSLTipText_llDetectedTouchUV">
-vector llDetectedTouchUV(integer number)
-returns the u and v coordinates in the first two components of a vector, for a triggered touch event
+vector llDetectedTouchUV(integer index)
+Returns the u and v coordinates in the first two components of a vector, for the texture coordinates where the prim was touched in a triggered touch event
 	</string>
 	<string name="LSLTipText_llDetectedTouchFace">
-integer llDetectedTouchFace(integer number)
-returns the index of the face on the object for a triggered touch event
+integer llDetectedTouchFace(integer index)
+Returns the index of the face where the avatar clicked in a triggered touch event
 	</string>
 	<string name="LSLTipText_llDetectedTouchPos">
-vector llDetectedTouchPos(integer number)
-returns the position touched for a triggered touch event
+vector llDetectedTouchPos(integer index)
+Returns the position where the object was touched in a triggered touch event
 	</string>
 	<string name="LSLTipText_llDetectedTouchNormal">
-vector llDetectedTouchNormal(integer number)
-returns the surface normal for a triggered touch event
+vector llDetectedTouchNormal(integer index)
+Returns the surface normal for a triggered touch event
 	</string>
 	<string name="LSLTipText_llDetectedTouchBinormal">
-vector llDetectedTouchBinormal(integer number)
-returns the surface binormal for a triggered touch event
+vector llDetectedTouchBinormal(integer index)
+Returns the surface binormal for a triggered touch event
 	</string>
 	<string name="LSLTipText_llDetectedTouchST">
-vector llDetectedTouchST(integer number)
-returns the s and t coordinates in the first two components of a vector, for a triggered touch event
+vector llDetectedTouchST(integer index)
+Returns the s and t coordinates in the first two components of a vector, for the surface coordinates where the prim was touched in a triggered touch event
 	</string>
 	<string name="LSLTipText_llSHA1String">
-string llSHA1String(string sr)
-Performs a SHA1 security Hash.  Returns a 40 character hex string.
+string llSHA1String(string src)
+Returns a string of 40 hex characters that is the SHA1 security Hash of src
 	</string>
 	<string name="LSLTipText_llGetFreeURLs">
 integer llGetFreeURLs()
-returns the available urls for the current script
+Returns the number of available URLs for the current script
 	</string>
 	<string name="LSLTipText_llRequestURL">
 key llRequestURL()
-Requests one HTTP:// url for use by this object
-Triggers an http_server event with results.
+Requests one HTTP:// url for use by this object.
+An http_request event is triggered with the results.
 	</string>
 	<string name="LSLTipText_llRequestSecureURL">
 key llRequestSecureURL()
-Requests one HTTPS:// (SSL) url for use by this object
-Triggers an http_server event with results.
+Requests one HTTPS:// (SSL) url for use by this object.
+An http_request event is triggered with the results.
 	</string>
 	<string name="LSLTipText_llReleaseURL">
 llReleaseURL(string url)
-Releases the specified URL, it will no longer be usable.
+Releases the specified URL, it will no longer be usable
 	</string>
 	<string name="LSLTipText_llHTTPResponse">
-llHTTPResponse(key id, integer status, string body)
-Responds to request id with status and body.
-	</string>
+llHTTPResponse(key request_id, integer status, string body)
+Responds to request_id with status and body
+  </string>
 	<string name="LSLTipText_llGetHTTPHeader">
-string llGetHTTPHeader(key id, string header)
-Get the value for header for request id.
-	</string>
-	
-	<!-- Avatar busy/away mode -->
+string llGetHTTPHeader(key request_id, string header)
+Returns the value for header for request_id
+	</string>
+  <string name="LSLTipText_llSetPrimMediaParams">
+llSetPrimMediaParams(integer face, list params)
+Sets the media params for a particular face on an object. If media is not already on this object, add it. 
+List is a set of name/value pairs in no particular order.  Params not specified are unchanged, or if new media is added then set to the default specified.
+The possible names are below, along with the types of values and what they mean.
+  </string>
+  <string name="LSLTipText_llGetPrimMediaParams">
+list llGetPrimMediaParams(integer face, list params)
+Returns the media params for a particular face on an object, given the desired list of names, in the order requested.
+(Returns an empty list if no media exists on the face.)
+  </string>
+  <string name="LSLTipText_llClearPrimMedia">
+llClearPrimMedia(integer face)
+Clears (deletes) the media and all params from the given face.
+  </string>
+
+  <!-- Avatar busy/away mode -->
 	<string name="AvatarSetNotAway">Set Not Away</string>
 	<string name="AvatarSetAway">Set Away</string>
 	<string name="AvatarSetNotBusy">Set Not Busy</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index cb876da8d8085be0e7ee9750404d3628348d1e24..824a815a99d90905d72c2a380342dc2fbc028049 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -10,9 +10,9 @@
              highlighted_color="ScrollHighlightedColor"
              column_padding="5"
              draw_stripes="true"
+             scroll_bar_bg_visible="false"
+             scroll_bar_bg_color="black"
              background_visible="false"
              heading_height="23"
              draw_border="false"
-             draw_heading="false"
-             scroll_bar_bg_visible="false"
-             scroll_bar_bg_color="black" />
+             draw_heading="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
index 6e73e997e062a59c81943e662860e41294bd7dad..e998635d201ec1f7488064556567d4ed04130534 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -12,17 +12,20 @@
  <combo_editor
   select_on_focus="true"
   text_pad_left="20" 
+  tool_tip="Search"
   background_image="TextField_Search_Off"
   background_image_disabled="TextField_Search_Disabled"
   background_image_focused="TextField_Search_Active"/>
  <combo_list
   multi_select="false"
-  page_lines="10" />
+  page_lines="10"
+  scroll_bar_bg_visible="true" />
  <search_button label=""
   top_pad="4"
   left_pad="4" 
   width="13"
   height="13" 
+  tool_tip="Search"
   image_unselected="Search"
   image_selected="Search" />
 </search_combo_box>
\ No newline at end of file
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..40f7d532bc6846280c2e60b501ab69eaa851213c
--- /dev/null
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -0,0 +1,127 @@
+/** 
+ * @file llviewerhelputil_test.cpp
+ * @brief LLViewerHelpUtil tests
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-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 "../test/lltut.h"
+
+#include "../llviewerhelputil.h"
+#include "llcontrol.h"
+#include "llsys.h"
+
+#include <iostream>
+
+//----------------------------------------------------------------------------
+// Implementation of enough of LLControlGroup to support the tests:
+
+static std::map<std::string,std::string> test_stringvec;
+
+LLControlGroup::LLControlGroup(const std::string& name)
+	: LLInstanceTracker<LLControlGroup, std::string>(name)
+{
+}
+
+LLControlGroup::~LLControlGroup()
+{
+}
+
+// Implementation of just the LLControlGroup methods we requre
+BOOL LLControlGroup::declareString(const std::string& name,
+				   const std::string& initial_val,
+				   const std::string& comment,
+				   BOOL persist)
+{
+	test_stringvec[name] = initial_val;
+	return true;
+}
+
+void LLControlGroup::setString(const std::string& name, const std::string& val)
+{
+	test_stringvec[name] = val;
+}
+
+std::string LLControlGroup::getString(const std::string& name)
+{
+	return test_stringvec[name];
+}
+
+//----------------------------------------------------------------------------
+	
+namespace tut
+{
+    struct viewerhelputil
+    {
+    };
+    
+	typedef test_group<viewerhelputil> viewerhelputil_t;
+	typedef viewerhelputil_t::object viewerhelputil_object_t;
+	tut::viewerhelputil_t tut_viewerhelputil("viewerhelputil");
+
+	template<> template<>
+	void viewerhelputil_object_t::test<1>()
+	{
+		LLOSInfo osinfo;
+		LLControlGroup cgr("test");
+		cgr.declareString("HelpURLFormat", "fooformat", "declared_for_test", FALSE);
+		cgr.declareString("VersionChannelName", "foochannelname", "declared_for_test", FALSE);
+		cgr.declareString("Language", "foolanguage", "declared_for_test", FALSE);
+		std::string topic("test_topic");
+
+		std::string subresult;
+
+		cgr.setString("HelpURLFormat", "fooformat");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("no substitution tags", subresult, "fooformat");
+
+		cgr.setString("HelpURLFormat", "");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("blank substitution format", subresult, "");
+
+		cgr.setString("HelpURLFormat", "[LANGUAGE]");
+		cgr.setString("Language", "");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("simple substitution with blank", subresult, "");
+
+		cgr.setString("HelpURLFormat", "[LANGUAGE]");
+		cgr.setString("Language", "Esperanto");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("simple substitution", subresult, "Esperanto");
+
+		cgr.setString("HelpURLFormat", "[XXX]");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("unknown substitution", subresult, "[XXX]");
+
+		cgr.setString("HelpURLFormat", "[LANGUAGE]/[LANGUAGE]");
+		cgr.setString("Language", "Esperanto");
+		subresult = LLViewerHelpUtil::buildHelpURL(topic, cgr, osinfo);
+		ensure_equals("multiple substitution", subresult, "Esperanto/Esperanto");
+	}
+    
+}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e85fddbc991f0decf4066219d54bf67f541712ea..036fa4923ff100cd4390faec0b3e2a3bb3d14e0a 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -169,6 +169,12 @@ def construct(self):
         # the final exe is complicated because we're not sure where it's coming from,
         # nor do we have a fixed name for the executable
         self.path(self.find_existing_file('debug/secondlife-bin.exe', 'release/secondlife-bin.exe', 'relwithdebinfo/secondlife-bin.exe'), dst=self.final_exe())
+
+        # Plugin host application
+        self.path(os.path.join(os.pardir,
+                               'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"),
+                  "slplugin.exe")
+ 
         # need to get the kdu dll from any of the build directories as well
         try:
             self.path(self.find_existing_file('../llkdu/%s/llkdu.dll' % self.args['configuration'],
@@ -193,11 +199,6 @@ def construct(self):
             self.path("openjpeg.dll")
             self.end_prefix()
 
-        # Plugin host application
-        if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("slplugin.exe")
-            self.end_prefix()
-
         # Media plugins - QuickTime
         if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
             self.path("media_plugin_quicktime.dll")
@@ -248,10 +249,12 @@ def construct(self):
         # Vivox runtimes
         if self.prefix(src="vivox-runtime/i686-win32", dst=""):
             self.path("SLVoice.exe")
-            self.path("alut.dll")
+            self.path("libsndfile-1.dll")
+            self.path("zlib1.dll")
             self.path("vivoxsdk.dll")
+            self.path("vivoxplatform.dll")
             self.path("ortp.dll")
-            self.path("wrap_oal.dll")
+            self.path("vivoxoal.dll")
             self.end_prefix()
 
         # pull in the crash logger and updater from other projects
@@ -461,10 +464,11 @@ def construct(self):
                 self.path("zh-Hans.lproj")
 
                 # SLVoice and vivox lols
-                self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib")
-                self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib")
+                self.path("vivox-runtime/universal-darwin/libsndfile.dylib", "libsndfile.dylib")
+                self.path("vivox-runtime/universal-darwin/libvivoxoal.dylib", "libvivoxoal.dylib")
                 self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib")
                 self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib")
+                self.path("vivox-runtime/universal-darwin/libvivoxplatform.dylib", "libvivoxplatform.dylib")
                 self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice")
 
                 # need to get the kdu dll from any of the build directories as well
@@ -484,9 +488,11 @@ def construct(self):
                 self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
                 self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
 
+                # plugin launcher
+                self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
+
                 # plugins
                 if self.prefix(src="", dst="llplugin"):
-                    self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
                     self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
                     self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
                     self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
@@ -677,6 +683,7 @@ def construct(self):
         self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
         self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
         self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
+        self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
         if self.prefix("res-sdl"):
             self.path("*")
             # recurse
@@ -684,7 +691,6 @@ def construct(self):
 
         # plugins
         if self.prefix(src="", dst="bin/llplugin"):
-            self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
             self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
             self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
             self.end_prefix("bin/llplugin")
@@ -715,7 +721,10 @@ def construct(self):
                     self.end_prefix()
             if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
                     self.path("libortp.so")
+                    self.path("libsndfile.so.1")
+                    self.path("libvivoxoal.so.1")
                     self.path("libvivoxsdk.so")
+                    self.path("libvivoxplatform.so")
                     self.end_prefix("lib")
 
 class Linux_x86_64Manifest(LinuxManifest):
diff --git a/install.xml b/install.xml
index 225dc76a9aff0e6915c53d275434d47b6a61910b..0f8b4ac46517d831e2934c5479e7977065c12cf4 100644
--- a/install.xml
+++ b/install.xml
@@ -1334,23 +1334,23 @@ anguage Infrstructure (CLI) international standard</string>
           <key>darwin</key>
           <map>
             <key>md5sum</key>
-            <string>8675b5eedef038b514338b17f0e55961</string>
+            <string>3eb4b31e92e16567e2fa967df9f9b845</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-darwin-20090309.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-darwin-20090930a.tar.bz2</uri>
           </map>
           <key>linux</key>
           <map>
             <key>md5sum</key>
-            <string>01573510dce7f380f44e561ef2f3dd9f</string>
+            <string>61ab6acd1f4736c5260c492bb60c26af</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-linux-20090309.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-linux-20090930a.tar.bz2</uri>
           </map>
           <key>windows</key>
           <map>
             <key>md5sum</key>
-            <string>752daa90e07c05202d1f76980cb955eb</string>
+            <string>ad5737dbfab87a13b23451b68248b22a</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-windows-20090309.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.0.0006.7278-windows-20090930a.tar.bz2</uri>
           </map>
         </map>
       </map>