diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 1ccdb0f20bb0343bb33acc7b57641bca1ace5600..84e3477ce62933b9ea231bb169fc1d09f19995a3 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -11,6 +11,7 @@ include(LLCommon)
 include(LLImage)
 include(LLImageJ2COJ)   # ugh, needed for images
 include(LLMath)
+include(LLMessage)
 include(LLRender)
 include(LLWindow)
 include(LLUI)
@@ -67,6 +68,7 @@ endif (DARWIN)
 # Sort by high-level to low-level
 target_link_libraries(llui_libtest
     llui
+    llmessage
     ${OS_LIBRARIES}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     )
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index b93890ab32578c6163d9da54c897b98e39d5a777..4b0bf6a2d9f94b5c7dfc23acf4edad7089131a3f 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -90,7 +90,7 @@ bool translate_init(std::string comma_delim_path_list,
 
 	// extract paths string vector from comma-delimited flat string
 	std::vector<std::string> paths;
-	LLStringUtil::getTokens(comma_delim_path_list, paths); // split over ','
+	LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ','
 
 	// suck the translation xml files into memory
 	LLXMLNodePtr root;
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 80245fd569b9c52e558d8a8ffaa513a99ea98ded..9e9e1aaeaecf4121ef51793b30ee500c6f59d580 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -62,7 +62,8 @@ if (FMOD)
     if (LINUX)
       if (${CXX_VERSION} MATCHES "4.[23]")
         set_source_files_properties(llaudioengine_fmod.cpp
-                                    COMPILE_FLAGS -Wno-error=write-strings)
+                                    llstreamingaudio_fmod.cpp
+                                    COMPILE_FLAGS -Wno-write-strings)
       endif (${CXX_VERSION} MATCHES "4.[23]")
     endif (LINUX)
 endif (FMOD)
diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h
index 7b010d6739c0a4f3f14c80cfa1b67f65e4630efd..acd0da61a4bf2d0049577089490eeddeebd16f9b 100644
--- a/indra/llcommon/llchat.h
+++ b/indra/llcommon/llchat.h
@@ -65,6 +65,12 @@ typedef enum e_chat_audible_level
 	CHAT_AUDIBLE_FULLY = 1
 } EChatAudible;
 
+typedef enum e_chat_style
+{
+	CHAT_STYLE_NORMAL,
+	CHAT_STYLE_IRC
+}EChatStyle;
+
 // A piece of chat
 class LLChat
 {
@@ -79,7 +85,8 @@ class LLChat
 		mMuted(FALSE),
 		mTime(0.0),
 		mPosAgent(),
-		mURL()
+		mURL(),
+		mChatStyle(CHAT_STYLE_NORMAL)
 	{ }
 	
 	std::string		mText;		// UTF-8 line of text
@@ -92,6 +99,7 @@ class LLChat
 	F64				mTime;		// viewer only, seconds from viewer start
 	LLVector3		mPosAgent;
 	std::string		mURL;
+	EChatStyle		mChatStyle;
 };
 
 #endif
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 7bc9e16bc98dd4556e7365df2684b34d0cefe908..6a82a848bea99086e5f8c9f232ff55cd31c45e8e 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -94,8 +94,12 @@ std::string LLDate::asRFC1123() const
 	return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
 }
 
+LLFastTimer::DeclareTimer FT_DATE_FORMAT("Date Format");
+
 std::string LLDate::toHTTPDateString (std::string fmt) const
 {
+	LLFastTimer ft1(FT_DATE_FORMAT);
+	
 	std::ostringstream stream;
 	time_t locSeconds = (time_t) mSecondsSinceEpoch;
 	struct tm * gmt = gmtime (&locSeconds);
@@ -107,6 +111,8 @@ std::string LLDate::toHTTPDateString (std::string fmt) const
 
 std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
 {
+	LLFastTimer ft1(FT_DATE_FORMAT);
+	
 	std::ostringstream stream;
 	stream.imbue (std::locale(LLStringUtil::getLocale().c_str()));
 	toHTTPDateStream (stream, gmt, fmt);
@@ -115,11 +121,11 @@ std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
 
 void LLDate::toHTTPDateStream(std::ostream& s, tm * gmt, std::string fmt)
 {
-	using namespace std;
+	LLFastTimer ft1(FT_DATE_FORMAT);
 
 	const char * pBeg = fmt.c_str();
 	const char * pEnd = pBeg + fmt.length();
-	const time_put<char>& tp = use_facet<time_put<char> >(s.getloc());
+	const std::time_put<char>& tp = std::use_facet<std::time_put<char> >(s.getloc());
 	tp.put (s, s, s.fill(), gmt, pBeg, pEnd);
 }
 
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index d7da40d64597e9e9eb26cd089a15edd5749c24db..78e835dc95f9652750b72be5c28f9faefe44a06f 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -42,7 +42,7 @@
 #include <winnls.h> // for WideCharToMultiByte
 #endif
 
-LLFastTimer::DeclareTimer STRING_LOCALIZATION("String Localization");
+LLFastTimer::DeclareTimer FT_STRING_FORMAT("String Format");
 
 
 std::string ll_safe_string(const char* in)
@@ -776,12 +776,12 @@ namespace LLStringFn
 	// https://wiki.lindenlab.com/wiki/Unicode_Guidelines has details on
 	// allowable code points for XML. Specifically, they are:
 	// 0x09, 0x0a, 0x0d, and 0x20 on up.  JC
-	std::string strip_invalid_xml(const std::string& input)
+	std::string strip_invalid_xml(const std::string& instr)
 	{
 		std::string output;
-		output.reserve( input.size() );
-		std::string::const_iterator it = input.begin();
-		while (it != input.end())
+		output.reserve( instr.size() );
+		std::string::const_iterator it = instr.begin();
+		while (it != instr.end())
 		{
 			// Must compare as unsigned for >=
 			// Test most likely match first
@@ -817,6 +817,315 @@ namespace LLStringFn
 	}
 }
 
+////////////////////////////////////////////////////////////
+
+//static
+template<> 
+void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims)
+{
+	std::string currToken;
+	std::string::size_type begIdx, endIdx;
+
+	begIdx = instr.find_first_not_of (delims);
+	while (begIdx != std::string::npos)
+	{
+		endIdx = instr.find_first_of (delims, begIdx);
+		if (endIdx == std::string::npos)
+		{
+			endIdx = instr.length();
+		}
+
+		currToken = instr.substr(begIdx, endIdx - begIdx);
+		LLStringUtil::trim (currToken);
+		tokens.push_back(currToken);
+		begIdx = instr.find_first_not_of (delims, endIdx);
+	}
+}
+
+template<> 
+LLStringUtil::size_type LLStringUtil::getSubstitution(const std::string& instr, size_type& start, std::vector<std::string>& tokens)
+{
+	const std::string delims (",");
+	
+	// Find the first ]
+	size_type pos2 = instr.find(']', start);
+	if (pos2 == std::string::npos)
+		return std::string::npos;
+
+	// Find the last [ before ]
+	size_type pos1 = instr.find_last_of('[', pos2-1);
+	if (pos1 == std::string::npos || pos1 < start)
+		return std::string::npos;
+	
+	getTokens(std::string(instr,pos1+1,pos2-pos1-1), tokens, delims);
+	start = pos2+1;
+	
+	return pos1;
+}
+
+// static
+template<> 
+bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const format_map_t& substitutions)
+{
+	// see if we have a replacement for the bracketed string (without the brackets)
+	// test first using has() because if we just look up with operator[] we get back an
+	// empty string even if the value is missing. We want to distinguish between 
+	// missing replacements and deliberately empty replacement strings.
+	format_map_t::const_iterator iter = substitutions.find(token);
+	if (iter != substitutions.end())
+	{
+		replacement = iter->second;
+		return true;
+	}
+	// if not, see if there's one WITH brackets
+	iter = substitutions.find(std::string("[" + token + "]"));
+	if (iter != substitutions.end())
+	{
+		replacement = iter->second;
+		return true;
+	}
+
+	return false;
+}
+
+// static
+template<> 
+bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const LLSD& substitutions)
+{
+	// see if we have a replacement for the bracketed string (without the brackets)
+	// test first using has() because if we just look up with operator[] we get back an
+	// empty string even if the value is missing. We want to distinguish between 
+	// missing replacements and deliberately empty replacement strings.
+	if (substitutions.has(token))
+	{
+		replacement = substitutions[token].asString();
+		return true;
+	}
+	// if not, see if there's one WITH brackets
+	else if (substitutions.has(std::string("[" + token + "]")))
+	{
+		replacement = substitutions[std::string("[" + token + "]")].asString();
+		return true;
+	}
+
+	return false;
+}
+
+// static
+template<> 
+void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
+{
+	std::stringstream strStream;
+	S32 intDecimals = 0;
+
+	convertToS32 (decimals, intDecimals);
+	if (!sLocale.empty())
+	{
+		strStream.imbue (std::locale(sLocale.c_str()));
+	}
+
+	if (!intDecimals)
+	{
+		S32 intStr;
+
+		if (convertToS32(numStr, intStr))
+		{
+			strStream << intStr;
+			numStr = strStream.str();
+		}
+	}
+	else
+	{
+		F32 floatStr;
+
+		if (convertToF32(numStr, floatStr))
+		{
+			strStream << std::fixed << std::showpoint << std::setprecision(intDecimals) << floatStr;
+			numStr = strStream.str();
+		}
+	}
+}
+
+// static
+template<> 
+bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
+								  std::string param, S32 secFromEpoch)
+{
+	if (param == "local")   // local
+	{
+		secFromEpoch -= LLStringOps::getLocalTimeOffset();
+	}
+	else if (param != "utc") // slt
+	{
+		secFromEpoch -= LLStringOps::getSltOffset();
+	}
+		
+	// if never fell into those two ifs above, param must be utc
+	if (secFromEpoch < 0) secFromEpoch = 0;
+
+	LLDate * datetime = new LLDate((F64)secFromEpoch);
+	std::string code = LLStringOps::getDatetimeCode (token);
+
+	// special case to handle timezone
+	if (code == "%Z") {
+		if (param == "utc") replacement = "GMT";
+		else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST";
+		return true;
+	}
+	replacement = datetime->toHTTPDateString(code);
+
+	if (code.empty())
+	{
+		return false;
+	}
+	else
+	{
+		return true;
+	}
+}
+
+// LLStringUtil::format recogizes the following patterns.
+// All substitutions *must* be encased in []'s in the input string.
+// The []'s are optional in the substitution map.
+// [FOO_123]
+// [FOO,number,precision]
+// [FOO,datetime,format]
+
+
+// static
+template<> 
+S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
+{
+	LLFastTimer ft(FT_STRING_FORMAT);
+	S32 res = 0;
+
+	std::string output;
+	std::vector<std::string> tokens;
+
+	std::string::size_type start = 0;
+	std::string::size_type prev_start = 0;
+	std::string::size_type key_start = 0;
+	while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos)
+	{
+		output += std::string(s, prev_start, key_start-prev_start);
+		prev_start = start;
+		
+		bool found_replacement = false;
+		std::string replacement;
+
+		if (tokens.size() == 1)
+		{
+			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+		}
+		else if (tokens[1] == "number")
+		{
+			std::string param = "0";
+
+			if (tokens.size() > 2) param = tokens[2];
+			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+			if (found_replacement) formatNumber (replacement, param);
+		}
+		else if (tokens[1] == "datetime")
+		{
+			std::string param;
+			if (tokens.size() > 2) param = tokens[2];
+			
+			format_map_t::const_iterator iter = substitutions.find("datetime");
+			if (iter != substitutions.end())
+			{
+				S32 secFromEpoch = 0;
+				BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch);
+				if (r)
+				{
+					found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch);
+				}
+			}
+		}
+
+		if (found_replacement)
+		{
+			output += replacement;
+			res++;
+		}
+		else
+		{
+			// we had no replacement, so leave the string we searched for so that it gets noticed by QA
+			// "hello [NAME_NOT_FOUND]" is output
+			output += std::string("[") + tokens[0] + std::string("]");
+		}
+		tokens.clear();
+	}
+	// send the remainder of the string (with no further matches for bracketed names)
+	output += std::string(s, start);
+	s = output;
+	return res;
+}
+
+//static
+template<> 
+S32 LLStringUtil::format(std::string& s, const LLSD& substitutions)
+{
+	LLFastTimer ft(FT_STRING_FORMAT);
+	S32 res = 0;
+
+	if (!substitutions.isMap()) 
+	{
+		return res;
+	}
+
+	std::string output;
+	std::vector<std::string> tokens;
+
+	std::string::size_type start = 0;
+	std::string::size_type prev_start = 0;
+	std::string::size_type key_start = 0;
+	while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos)
+	{
+		output += std::string(s, prev_start, key_start-prev_start);
+		prev_start = start;
+		
+		bool found_replacement = false;
+		std::string replacement;
+
+		if (tokens.size() == 1)
+		{
+			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+		}
+		else if (tokens[1] == "number")
+		{
+			std::string param = "0";
+
+			if (tokens.size() > 2) param = tokens[2];
+			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+			if (found_replacement) formatNumber (replacement, param);
+		}
+		else if (tokens[1] == "datetime")
+		{
+			std::string param;
+			if (tokens.size() > 2) param = tokens[2];
+			
+			S32 secFromEpoch = (S32) substitutions["datetime"].asInteger();
+			found_replacement = formatDatetime (replacement, tokens[0], param, secFromEpoch);
+		}
+
+		if (found_replacement)
+		{
+			output += replacement;
+			res++;
+		}
+		else
+		{
+			// we had no replacement, so leave the string we searched for so that it gets noticed by QA
+			// "hello [NAME_NOT_FOUND]" is output
+			output += std::string("[") + tokens[0] + std::string("]");
+		}
+		tokens.clear();
+	}
+	// send the remainder of the string (with no further matches for bracketed names)
+	output += std::string(s, start);
+	s = output;
+	return res;
+}
 
 ////////////////////////////////////////////////////////////
 // Testing
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index c6dcdd6d12f106f5e9fff3e5dfc5269de87dcaa0..3b1379c76ae47243d30da2c50f0fa9a001e1a0b9 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -231,7 +231,8 @@ class LLStringUtilBase
 	static std::basic_string<T> null;
 	
 	typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
-	static void getTokens (std::basic_string<T> input, std::vector<std::basic_string<T> >& tokens);
+	static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
+	static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
 	static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
 	static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
 	static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
@@ -597,302 +598,12 @@ namespace LLStringFn
 }
 
 ////////////////////////////////////////////////////////////
+// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
+// There is no LLWStringUtil::format implementation currently.
+// Calling thse for anything other than LLStringUtil will produce link errors.
 
-//static
-template<class T>
-void LLStringUtilBase<T>::getTokens (std::basic_string<T> input, std::vector<std::basic_string<T> >& tokens)
-{
-	const std::basic_string<T> delims (",");
-	std::basic_string<T> currToken;
-	size_type begIdx, endIdx;
-
-	begIdx = input.find_first_not_of (delims);
-	while (begIdx != std::basic_string<T>::npos)
-	{
-		endIdx = input.find_first_of (delims, begIdx);
-		if (endIdx == std::basic_string<T>::npos)
-		{
-			endIdx = input.length();
-		}
-
-		currToken = input.substr(begIdx, endIdx - begIdx);
-		trim (currToken);
-		tokens.push_back(currToken);
-		begIdx = input.find_first_not_of (delims, endIdx);
-	}
-}
-
-extern LLFastTimer::DeclareTimer STRING_LOCALIZATION;
-
-// static
-template<class T> 
-S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& substitutions)
-{
-	LLFastTimer ft(STRING_LOCALIZATION);
-	S32 res = 0;
-
-	std::basic_ostringstream<T> output;
-	// match strings like [NAME,number,3]
-	const boost::regex key("\\[((\\s)*([0-9_A-Za-z]+)((\\s)*,(\\s)*[0-9_A-Za-z\\s]*){0,2}(\\s)*)]");
-
-
-	typename std::basic_string<T>::const_iterator start = s.begin();
-	typename std::basic_string<T>::const_iterator end = s.end();
-	boost::smatch match;
-	
-
-	while (boost::regex_search(start, end, match, key, boost::match_default))
-	{
-		bool found_replacement = false;
-		std::vector<std::basic_string<T> > tokens;
-		std::basic_string<T> replacement;
-
-		getTokens (std::basic_string<T>(match[1].first, match[1].second), tokens);
-
-		if (tokens.size() == 1)
-		{
-			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
-		}
-		else if (tokens[1] == "number")
-		{
-			std::basic_string<T> param = "0";
-
-			if (tokens.size() > 2) param = tokens[2];
-			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
-			if (found_replacement) formatNumber (replacement, param);
-		}
-		else if (tokens[1] == "datetime")
-		{
-			std::basic_string<T> param;
-			if (tokens.size() > 2) param = tokens[2];
-			
-			format_map_t::const_iterator iter = substitutions.find("datetime");
-			if (iter != substitutions.end())
-			{
-				S32 secFromEpoch = 0;
-				BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch);
-				if (r)
-				{
-					found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch);
-				}
-			}
-		}
-
-		if (found_replacement)
-		{
-			output << std::basic_string<T>(start, match[0].first) << replacement;
-			res++;
-		}
-		else
-		{
-			// we had no replacement, so leave the string we searched for so that it gets noticed by QA
-			// "hello [NAME_NOT_FOUND]" is output
-			output << std::basic_string<T>(start, match[0].second);
-		}
-		
-		// update search position 
-		start = match[0].second; 
-	}
-	// send the remainder of the string (with no further matches for bracketed names)
-	output << std::basic_string<T>(start, end);
-	s = output.str();
-	return res;
-}
-
-//static
-template<class T>
-S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const LLSD& substitutions)
-{
-	LLFastTimer ft(STRING_LOCALIZATION);
-
-	S32 res = 0;
-
-	if (!substitutions.isMap()) 
-	{
-		return res;
-	}
-
-	std::basic_ostringstream<T> output;
-	// match strings like [NAME,number,3]
-	const boost::regex key("\\[((\\s)*([0-9_A-Za-z]+)((\\s)*,(\\s)*[0-9_A-Za-z\\s]*){0,2}(\\s)*)]");
-
-
-	typename std::basic_string<T>::const_iterator start = s.begin();
-	typename std::basic_string<T>::const_iterator end = s.end();
-	boost::smatch match;
-	
-
-	while (boost::regex_search(start, end, match, key, boost::match_default))
-	{
-		bool found_replacement = false;
-		std::vector<std::basic_string<T> > tokens;
-		std::basic_string<T> replacement;
-
-		getTokens (std::basic_string<T>(match[1].first, match[1].second), tokens);
-
-		if (tokens.size() == 1)
-		{
-			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
-		}
-		else if (tokens[1] == "number")
-		{
-			std::basic_string<T> param = "0";
-
-			if (tokens.size() > 2) param = tokens[2];
-			found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
-			if (found_replacement) formatNumber (replacement, param);
-		}
-		else if (tokens[1] == "datetime")
-		{
-			std::basic_string<T> param;
-			if (tokens.size() > 2) param = tokens[2];
-			
-			S32 secFromEpoch = (S32) substitutions["datetime"].asInteger();
-			found_replacement = formatDatetime (replacement, tokens[0], param, secFromEpoch);
-		}
-
-		if (found_replacement)
-		{
-			output << std::basic_string<T>(start, match[0].first) << replacement;
-			res++;
-		}
-		else
-		{
-			// we had no replacement, so leave the string we searched for so that it gets noticed by QA
-			// "hello [NAME_NOT_FOUND]" is output
-			output << std::basic_string<T>(start, match[0].second);
-		}
-		
-		// update search position 
-		start = match[0].second; 
-	}
-	// send the remainder of the string (with no further matches for bracketed names)
-	output << std::basic_string<T>(start, end);
-	s = output.str();
-	return res;
-}
-
-// static
-template<class T>
-bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const format_map_t& substitutions)
-{
-	// see if we have a replacement for the bracketed string (without the brackets)
-	// test first using has() because if we just look up with operator[] we get back an
-	// empty string even if the value is missing. We want to distinguish between 
-	// missing replacements and deliberately empty replacement strings.
-	format_map_t::const_iterator iter = substitutions.find(token);
-	if (iter != substitutions.end())
-	{
-		replacement = iter->second;
-		return true;
-	}
-	// if not, see if there's one WITH brackets
-	iter = substitutions.find(std::basic_string<T>("[" + token + "]"));
-	if (iter != substitutions.end())
-	{
-		replacement = iter->second;
-		return true;
-	}
-
-	return false;
-}
-
-// static
-template<class T>
-bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const LLSD& substitutions)
-{
-	// see if we have a replacement for the bracketed string (without the brackets)
-	// test first using has() because if we just look up with operator[] we get back an
-	// empty string even if the value is missing. We want to distinguish between 
-	// missing replacements and deliberately empty replacement strings.
-	if (substitutions.has(token))
-	{
-		replacement = substitutions[token].asString();
-		return true;
-	}
-	// if not, see if there's one WITH brackets
-	else if (substitutions.has(std::basic_string<T>("[" + token + "]")))
-	{
-		replacement = substitutions[std::basic_string<T>("[" + token + "]")].asString();
-		return true;
-	}
-
-	return false;
-}
-
-// static
-template<class T>
-void LLStringUtilBase<T>::formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals)
-{
-	typedef typename std::basic_string<T>::size_type string_size_type_t;
-	std::basic_stringstream<T> strStream;
-	S32 intDecimals = 0;
-
-	convertToS32 (decimals, intDecimals);
-	if (!sLocale.empty())
-	{
-		strStream.imbue (std::locale(sLocale.c_str()));
-	}
-
-	if (!intDecimals)
-	{
-		S32 intStr;
-
-		if (convertToS32(numStr, intStr))
-		{
-			strStream << intStr;
-			numStr = strStream.str();
-		}
-	}
-	else
-	{
-		F32 floatStr;
-
-		if (convertToF32(numStr, floatStr))
-		{
-			strStream << std::fixed << std::showpoint << std::setprecision(intDecimals) << floatStr;
-			numStr = strStream.str();
-		}
-	}
-}
-
-// static
-template<class T>
-bool LLStringUtilBase<T>::formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token,
-										 std::basic_string<T> param, S32 secFromEpoch)
-{
-	if (param == "local")   // local
-	{
-		secFromEpoch -= LLStringOps::getLocalTimeOffset();
-	}
-	else if (param != "utc") // slt
-	{
-		secFromEpoch -= LLStringOps::getSltOffset();
-	}
-		
-	// if never fell into those two ifs above, param must be utc
-	if (secFromEpoch < 0) secFromEpoch = 0;
-
-	LLDate * datetime = new LLDate((F64)secFromEpoch);
-	std::string code = LLStringOps::getDatetimeCode (token);
-
-	// special case to handle timezone
-	if (code == "%Z") {
-		if (param == "utc") replacement = "GMT";
-		else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST";
-		return true;
-	}
+////////////////////////////////////////////////////////////
 
-	replacement = datetime->toHTTPDateString(code);
-	if (code.empty())
-	{
-		return false;
-	}
-	else
-	{
-		return true;
-	}
-}
 
 // static
 template<class T> 
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 32f19d6be5d667ab53e54db1dfe08256aab19847..bd581e860f3a230dd919f9836e3d402c3c8aaf0b 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -99,7 +99,7 @@ class LLInventoryObject : public LLRefCount
 	BOOL getIsLinkType() const;
 	// mutators - will not call updateServer();
 	void setUUID(const LLUUID& new_uuid);
-	void rename(const std::string& new_name);
+	virtual void rename(const std::string& new_name);
 	void setParent(const LLUUID& new_parent);
 	void setType(LLAssetType::EType type);
 
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 99f364a5899351a2788c316512427fad2b54d685..45573cd817a93f1c634a29107be2d3949927fef6 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -105,7 +105,7 @@ bool removeSubString(std::string& str, const std::string& substr)
 	size_t pos = str.find(substr);
 	if (pos != string::npos)
 	{
-		str.erase(pos);
+		str.erase(pos, substr.size());
 		return true;
 	}
 	return false;
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 8b0fcc68c427ca5ac59db98b7488a3bd8b8e1f79..95d693cdc429dbfe9fd8ad040bfbd7b88dfc08bf 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -34,6 +34,8 @@ set(llui_SOURCE_FILES
     llconsole.cpp
     llcontainerview.cpp
     llctrlselectioninterface.cpp
+    lldockablefloater.cpp
+    lldockcontrol.cpp
     lldraghandle.cpp
     lleditmenuhandler.cpp
     llf32uictrl.cpp
@@ -47,7 +49,7 @@ set(llui_SOURCE_FILES
     llkeywords.cpp
     lllayoutstack.cpp
     lllineeditor.cpp
-    lllink.cpp
+    lllistctrl.cpp
     llmenugl.cpp
     llmodaldialog.cpp
     llmultifloater.cpp 
@@ -78,6 +80,7 @@ set(llui_SOURCE_FILES
     llstatview.cpp
     llstyle.cpp
     lltabcontainer.cpp
+    lltextbase.cpp
     lltextbox.cpp
     lltexteditor.cpp
     lltextparser.cpp
@@ -89,6 +92,10 @@ set(llui_SOURCE_FILES
     lluiimage.cpp
     lluistring.cpp
     llundo.cpp
+    llurlaction.cpp
+    llurlentry.cpp
+    llurlmatch.cpp
+    llurlregistry.cpp
     llviewborder.cpp
     llviewmodel.cpp
     llview.cpp
@@ -108,6 +115,8 @@ set(llui_HEADER_FILES
     llcontainerview.h
     llctrlselectioninterface.h
     lldraghandle.h
+    lldockablefloater.h
+    lldockcontrol.h
     lleditmenuhandler.h
     llf32uictrl.h
     llfiltereditor.h 
@@ -123,7 +132,7 @@ set(llui_HEADER_FILES
     lllayoutstack.h
     lllazyvalue.h
     lllineeditor.h
-    lllink.h
+    lllistctrl.h
     llmenugl.h
     llmodaldialog.h
     llmultifloater.h 
@@ -154,6 +163,7 @@ set(llui_HEADER_FILES
     llstatview.h
     llstyle.h
     lltabcontainer.h
+    lltextbase.h
     lltextbox.h
     lltexteditor.h
     lltextparser.h
@@ -167,6 +177,10 @@ set(llui_HEADER_FILES
     lluiimage.h
     lluistring.h
     llundo.h
+    llurlaction.h
+    llurlentry.h
+    llurlmatch.h
+    llurlregistry.h
     llviewborder.h
     llviewmodel.h
     llview.h
@@ -182,12 +196,21 @@ add_library (llui ${llui_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llui
-    llrender
-    llwindow
-    llimage
-    llvfs       # ugh, just for LLDir
-    llxuixml
-    llxml
-    llcommon    # must be after llimage, llwindow, llrender
-    llmath
+    ${LLMESSAGE_LIBRARIES}
+    ${LLRENDER_LIBRARIES}
+    ${LLWINDOW_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLVFS_LIBRARIES}    # ugh, just for LLDir
+    ${LLXUIXML_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
     )
+
+# Add tests
+include(LLAddBuildTest)
+SET(llui_TEST_SOURCE_FILES
+    llurlmatch.cpp
+    llurlentry.cpp
+    )
+LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 98e8c9a9883465144a6288d5dc07322328e2324b..bf58e199490609e12916c359329a1af0f368a06b 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -355,11 +355,19 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
 			setFocus(TRUE);
 		}
 
+		/*
+		 * ATTENTION! This call fires another mouse down callback.
+		 * If you wish to remove this call emit that signal directly
+		 * by calling LLUICtrl::mMouseDownSignal(x, y, mask);
+		 */
+		LLUICtrl::handleMouseDown(x, y, mask);
+
 		mMouseDownSignal(this, LLSD());
 
 		mMouseDownTimer.start();
 		mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();
 		mMouseHeldDownCount = 0;
+
 		
 		if (getSoundFlags() & MOUSE_DOWN)
 		{
@@ -378,6 +386,13 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
 		// Always release the mouse
 		gFocusMgr.setMouseCapture( NULL );
 
+		/*
+		 * ATTENTION! This call fires another mouse up callback.
+		 * If you wish to remove this call emit that signal directly
+		 * by calling LLUICtrl::mMouseUpSignal(x, y, mask);
+		 */
+		LLUICtrl::handleMouseUp(x, y, mask);
+
 		// Regardless of where mouseup occurs, handle callback
 		mMouseUpSignal(this, LLSD());
 
@@ -460,12 +475,16 @@ BOOL	LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
 {
+	LLUICtrl::onMouseEnter(x, y, mask);
+
 	if (isInEnabledChain())
 		mNeedsHighlight = TRUE;
 }
 
 void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
 {
+	LLUICtrl::onMouseLeave(x, y, mask);
+
 	mNeedsHighlight = FALSE;
 }
 
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0789d6502edcf17888a26ff6768b1140cff809a
--- /dev/null
+++ b/indra/llui/lldockablefloater.cpp
@@ -0,0 +1,86 @@
+/** 
+ * @file lldockablefloater.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ * 
+ * Copyright (c) 2000-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 "lldockablefloater.h"
+
+LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,
+		const LLSD& key, const Params& params) :
+	LLFloater(key, params), mDockControl(dockControl)
+{
+}
+
+LLDockableFloater::~LLDockableFloater()
+{
+}
+
+BOOL LLDockableFloater::postBuild()
+{
+	mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+	LLFloater::setDocked(true);
+	return LLView::postBuild();
+}
+
+void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
+{
+	if (docked)
+	{
+		mDockControl.get()->on();
+	}
+	else
+	{
+		mDockControl.get()->off();
+	}
+	LLFloater::setDocked(docked, pop_on_undock);
+}
+
+void LLDockableFloater::draw()
+{
+	mDockControl.get()->repositionDockable();
+	mDockControl.get()->drawToungue();
+	LLFloater::draw();
+}
+
+void LLDockableFloater::setDockControl(LLDockControl* dockControl)
+{
+	mDockControl.reset(dockControl);
+}
+const LLUIImagePtr& LLDockableFloater::getDockTongue()
+{
+	return mDockTongue;
+}
+
+LLDockControl* LLDockableFloater::getDockControl()
+{
+	return mDockControl.get();
+}
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ece78a92522bf0d636810a35ae9aaa40d7eb3a2
--- /dev/null
+++ b/indra/llui/lldockablefloater.h
@@ -0,0 +1,65 @@
+/** 
+ * @file lldockablefloater.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-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_DOCKABLEFLOATER_H
+#define LL_DOCKABLEFLOATER_H
+
+#include "llerror.h"
+#include "llfloater.h"
+#include "lldockcontrol.h"
+
+/**
+ * Represents floater that can dock.
+ * In case impossibility deriving from LLDockableFloater use LLDockControl.
+ */
+class LLDockableFloater : public LLFloater
+{
+public:
+	LOG_CLASS(LLDockableFloater);
+	LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams());
+	virtual ~LLDockableFloater();
+
+	/* virtula */BOOL postBuild();
+	/* virtual */void setDocked(bool docked, bool pop_on_undock = true);
+	/* virtual */void draw();
+
+protected:
+	void setDockControl(LLDockControl* dockControl);
+	LLDockControl* getDockControl();
+	const LLUIImagePtr& getDockTongue();
+
+private:
+	std::auto_ptr<LLDockControl> mDockControl;
+	LLUIImagePtr mDockTongue;
+};
+
+#endif /* LL_DOCKABLEFLOATER_H */
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bec7f04cc06372da35d5e873473444bc017d6550
--- /dev/null
+++ b/indra/llui/lldockcontrol.cpp
@@ -0,0 +1,126 @@
+/** 
+ * @file lldockcontrol.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ * 
+ * Copyright (c) 2000-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 "lldockcontrol.h"
+
+LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
+		const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) :
+	mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(
+			dockTongue)
+{
+	mDockAt = dockAt;
+	if (enabled)
+	{
+		on();
+	}
+	else
+	{
+		off();
+	}
+}
+
+LLDockControl::~LLDockControl()
+{
+}
+
+void LLDockControl::repositionDockable()
+{
+	if (mEnabled)
+	{
+		calculateDockablePosition();
+	}
+}
+
+void LLDockControl::calculateDockablePosition()
+{
+	LLRect dockRect = mDockWidget->calcScreenRect();
+	if (mPrevDockRect != dockRect || mRecalculateDocablePosition)
+	{
+		LLRect dockableRect = mDockableFloater->calcScreenRect();
+		LLRect rootRect = mDockableFloater->getRootView()->getRect();
+
+		S32 x = 0;
+		S32 y = 0;
+		switch (mDockAt)
+		{
+		case TOP:
+			x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+			y = dockRect.mTop + mDockTongue->getHeight()
+					+ dockableRect.getHeight();
+			if (x < rootRect.mLeft)
+			{
+				x = rootRect.mLeft;
+			}
+			if (x + dockableRect.getWidth() > rootRect.mRight)
+			{
+				x = rootRect.mRight - dockableRect.getWidth();
+			}
+			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+			mDockTongueY = dockRect.mTop;
+			break;
+		}
+		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+				dockableRect.getHeight());
+		LLRect localDocableParentRect;
+		mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+				&localDocableParentRect);
+		mDockableFloater->setRect(localDocableParentRect);
+
+		mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+				&mDockTongueX, &mDockTongueY);
+		mPrevDockRect = dockRect;
+		mRecalculateDocablePosition = false;
+	}
+}
+
+void LLDockControl::on()
+{
+	mDockableFloater->setCanDrag(false);
+	mEnabled = true;
+	mRecalculateDocablePosition = true;
+}
+
+void LLDockControl::off()
+{
+	mDockableFloater->setCanDrag(true);
+	mEnabled = false;
+}
+
+void LLDockControl::drawToungue()
+{
+	if (mEnabled)
+	{
+		mDockTongue->draw(mDockTongueX, mDockTongueY);
+	}
+}
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e1f4c8e64e8df05f0b717dee947b911d59745cd
--- /dev/null
+++ b/indra/llui/lldockcontrol.h
@@ -0,0 +1,81 @@
+/** 
+ * @file lldockcontrol.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-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_DOCKCONTROL_H
+#define LL_DOCKCONTROL_H
+
+#include "llerror.h"
+#include "llview.h"
+#include "llfloater.h"
+#include "lluiimage.h"
+
+/**
+ * Provides services for docking of specified floater.
+ * This class should be used in case impossibility deriving from LLDockableFloater.
+ */
+class LLDockControl
+{
+public:
+	enum DocAt
+	{
+		TOP
+	};
+
+public:
+	LOG_CLASS(LLDockControl);
+	LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
+			const LLUIImagePtr& dockTongue, DocAt dockAt,
+			bool enabled);
+	virtual ~LLDockControl();
+
+public:
+	void on();
+	void off();
+	void setDock(LLView* dockWidget)
+	{	mDockWidget = dockWidget;};
+	void repositionDockable();
+	void drawToungue();
+protected:
+	virtual void calculateDockablePosition();
+private:
+	bool mEnabled;
+	bool mRecalculateDocablePosition;
+	DocAt mDockAt;
+	LLView* mDockWidget;
+	LLRect mPrevDockRect;
+	LLFloater* mDockableFloater;
+	LLUIImagePtr mDockTongue;
+	S32 mDockTongueX;
+	S32 mDockTongueY;
+};
+
+#endif /* LL_DOCKCONTROL_H */
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 13f862f3af54d04e596a48487efb726830cd7ab2..556ff8099118f1d997285c42de77cd3d694ab1cb 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -66,9 +66,12 @@ static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container")
 #include "llscrollingpanellist.h"
 #include "llcontainerview.h"
 #include "llpanel.h"
+#include "lllistctrl.h"
+
 static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list");
 static ScrollContainerRegistry::Register<LLContainerView> r2("container_view");
 static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML);
+static ScrollContainerRegistry::Register<LLListCtrl> r4("list");
 
 LLScrollContainer::Params::Params()
 :	is_opaque("opaque"),
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 637642cdcd1f5df0e9cebd8bc617be4ba96d4f04..36a3b007b620d9d8b3cd43887f08a656c556a2ae 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -57,6 +57,11 @@
 #include "llviewborder.h"
 #include "lltextbox.h"
 #include "llsdparam.h"
+#include "llcachename.h"
+#include "llmenugl.h"
+#include "llurlaction.h"
+
+#include <boost/bind.hpp>
 
 static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list");
 
@@ -118,6 +123,7 @@ LLScrollListCtrl::Params::Params()
 	sort_ascending("sort_ascending", true),
 	commit_on_keyboard_movement("commit_on_keyboard_movement", true),
 	heading_height("heading_height"),
+	page_lines("page_lines", 0),
 	background_visible("background_visible"),
 	draw_stripes("draw_stripes"),
 	column_padding("column_padding"),
@@ -140,7 +146,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 :	LLUICtrl(p),
 	mLineHeight(0),
 	mScrollLines(0),
-	mPageLines(0),
+	mPageLines(p.page_lines),
 	mMaxSelectable(0),
 	mAllowKeyboardMovement(TRUE),
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
@@ -157,6 +163,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mOnSortChangedCallback( NULL ),
 	mHighlightedItem(-1),
 	mBorder(NULL),
+	mPopupMenu(NULL),
 	mNumDynamicWidthColumns(0),
 	mTotalStaticColumnWidth(0),
 	mTotalColumnPadding(0),
@@ -179,7 +186,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mHighlightedColor(p.highlighted_color()),
 	mHoveredColor(p.hovered_color()),
 	mSearchColumn(p.search_column),
-	mColumnPadding(p.column_padding)
+	mColumnPadding(p.column_padding),
+	mContextMenuType(MENU_NONE)
 {
 	mItemListRect.setOriginAndSize(
 		mBorderThickness,
@@ -189,8 +197,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 
 	updateLineHeight();
 
-	mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0;
-
 	// Init the scrollbar
 	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 
@@ -207,7 +213,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	sbparams.orientation(LLScrollbar::VERTICAL);
 	sbparams.doc_size(getItemCount());
 	sbparams.doc_pos(mScrollLines);
-	sbparams.page_size(mPageLines);
+	sbparams.page_size( mPageLines ? mPageLines : getItemCount() );
 	sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
 	sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
 	sbparams.visible(false);
@@ -462,8 +468,12 @@ void LLScrollListCtrl::updateLayout()
 	getChildView("comment_text")->setShape(mItemListRect);
 
 	// how many lines of content in a single "page"
-	mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0;
-	BOOL scrollbar_visible = getItemCount() > mPageLines;
+	S32 page_lines =  mLineHeight? mItemListRect.getHeight() / mLineHeight : getItemCount();
+	//if mPageLines is NOT provided display all item
+	if(mPageLines)
+		page_lines = mPageLines;
+
+	BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight();
 	if (scrollbar_visible)
 	{
 		// provide space on the right for scrollbar
@@ -472,7 +482,7 @@ void LLScrollListCtrl::updateLayout()
 
 	mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - scrollbar_size, mItemListRect.mBottom);
 	mScrollbar->reshape(scrollbar_size, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0));
-	mScrollbar->setPageSize( mPageLines );
+	mScrollbar->setPageSize(page_lines);
 	mScrollbar->setDocSize( getItemCount() );
 	mScrollbar->setVisible(scrollbar_visible);
 
@@ -484,6 +494,9 @@ void LLScrollListCtrl::updateLayout()
 void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height)
 {
 	S32 height = llmin( getRequiredRect().getHeight(), max_height );
+	if(mPageLines)
+		height = llmin( mPageLines * mLineHeight + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
+
 	S32 width = getRect().getWidth();
 
 	reshape( width, height );
@@ -714,6 +727,12 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
 	updateLayout();
 
 }
+void LLScrollListCtrl::setPageLines(S32 new_page_lines)
+{
+	mPageLines  = new_page_lines;
+	
+	updateLayout();
+}
 
 BOOL LLScrollListCtrl::selectFirstItem()
 {
@@ -1360,7 +1379,7 @@ void LLScrollListCtrl::drawItems()
 	S32 y = mItemListRect.mTop - mLineHeight;
 
 	// allow for partial line at bottom
-	S32 num_page_lines = mPageLines + 1;
+	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
 
 	LLRect item_rect;
 
@@ -1692,6 +1711,72 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 	return LLUICtrl::handleMouseUp(x, y, mask);
 }
 
+// virtual
+BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	LLScrollListItem *item = hitItem(x, y);
+	if (item)
+	{
+		// check to see if we have a UUID for this row
+		std::string id = item->getValue().asString();
+		LLUUID uuid(id);
+		if (! uuid.isNull() && mContextMenuType != MENU_NONE)
+		{
+			// set up the callbacks for all of the avatar/group menu items
+			// (N.B. callbacks don't take const refs as id is local scope)
+			bool is_group = (mContextMenuType == MENU_GROUP);
+			LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
+			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
+			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
+
+			// create the context menu from the XUI file and display it
+			std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
+			delete mPopupMenu;
+			mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+				menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+			if (mPopupMenu)
+			{
+				mPopupMenu->show(x, y);
+				LLMenuGL::showPopup(this, mPopupMenu, x, y);
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
+void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+{
+	// show the resident's profile or the group profile
+	std::string sltype = is_group ? "group" : "agent";
+	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
+	LLUrlAction::clickAction(slurl);
+}
+
+void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
+{
+	// copy the name of the avatar or group to the clipboard
+	std::string name;
+	if (is_group)
+	{
+		gCacheName->getGroupName(LLUUID(id), name);
+	}
+	else
+	{
+		gCacheName->getFullName(LLUUID(id), name);
+	}
+	LLUrlAction::copyURLToClipboard(name);
+}
+
+void LLScrollListCtrl::copySLURLToClipboard(std::string id, bool is_group)
+{
+	// copy a SLURL for the avatar or group to the clipboard
+	std::string sltype = is_group ? "group" : "agent";
+	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
+	LLUrlAction::copyURLToClipboard(slurl);
+}
+
 BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
 	//BOOL handled = FALSE;
@@ -1783,7 +1868,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )
 		mLineHeight );
 
 	// allow for partial line at bottom
-	S32 num_page_lines = mPageLines + 1;
+	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
 
 	S32 line = 0;
 	item_list::iterator iter;
@@ -2348,7 +2433,8 @@ void LLScrollListCtrl::scrollToShowSelected()
 	}
 
 	S32 lowest = mScrollLines;
-	S32 highest = mScrollLines + mPageLines;
+	S32 page_lines = (mPageLines)? mPageLines : getItemCount();
+	S32 highest = mScrollLines + page_lines;
 
 	if (index < lowest)
 	{
@@ -2357,7 +2443,7 @@ void LLScrollListCtrl::scrollToShowSelected()
 	}
 	else if (highest <= index)
 	{
-		setScrollPos(index - mPageLines + 1);
+		setScrollPos(index - page_lines + 1);
 	}
 }
 
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 253a58ab73226438c95c8de7520fd04a8c71a5b5..5c18f85160eb5e04771c7b05ced0bfe46d045b97 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -54,6 +54,7 @@
 
 class LLScrollListCell;
 class LLTextBox;
+class LLContextMenu;
 
 class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, 
 	public LLCtrlListInterface, public LLCtrlScrollInterface
@@ -86,6 +87,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 		// layout
 		Optional<S32>	column_padding,
+							page_lines,
 						heading_height;
 
 		// sort and search behavior
@@ -270,10 +272,15 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	void			clearSearchString() { mSearchString.clear(); }
 
+	// support right-click context menus for avatar/group lists
+	enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
+	void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
+
 	// Overridden from LLView
 	/*virtual*/ void    draw();
 	/*virtual*/ BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask);
@@ -308,6 +315,11 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	S32 getMaxContentWidth() { return mMaxContentWidth; }
 
 	void setHeadingHeight(S32 heading_height);
+	/**
+	 * Sets  max visible  lines without scroolbar, if this value equals to 0,
+	 * then display all items.
+	 */
+	void setPageLines(S32 page_lines );
 	void setCollapseEmptyColumns(BOOL collapse);
 
 	LLScrollListItem*	hitItem(S32 x,S32 y);
@@ -362,11 +374,13 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	typedef std::deque<LLScrollListItem *> item_list;
 	item_list&		getItemList() { return mItemList; }
 
+	void			updateLineHeight();
+
 private:
 	void			selectPrevItem(BOOL extend_selection);
 	void			selectNextItem(BOOL extend_selection);
 	void			drawItems();
-	void			updateLineHeight();
+	
 	void            updateLineHeightInsert(LLScrollListItem* item);
 	void			reportInvalidInput();
 	BOOL			isRepeatedChars(const LLWString& string) const;
@@ -375,6 +389,10 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void			commitIfChanged();
 	BOOL			setSort(S32 column, BOOL ascending);
 
+	static void		showNameDetails(std::string id, bool is_group);
+	static void		copyNameToClipboard(std::string id, bool is_group);
+	static void		copySLURLToClipboard(std::string id, bool is_group);
+
 	S32				mLineHeight;	// the max height of a single line
 	S32				mScrollLines;	// how many lines we've scrolled down
 	S32				mPageLines;		// max number of lines is it possible to see on the screen given mRect and mLineHeight
@@ -421,6 +439,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	S32				mHighlightedItem;
 	class LLViewBorder*	mBorder;
+	LLContextMenu	*mPopupMenu;
 
 	LLWString		mSearchString;
 	LLFrameTimer	mSearchTimer;
@@ -438,6 +457,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	BOOL			mDirty;
 	S32				mOriginalSelection;
 
+	ContextMenuType mContextMenuType;
+
 	typedef std::vector<LLScrollListColumn*> ordered_columns_t;
 	ordered_columns_t	mColumnsIndexed;
 
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index 929a809d88ed518b0e59912173680cc651afbd5f..c16ac0801443a5f4a499dc627bb8efba0dd112e3 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -54,8 +54,6 @@ LLStyle::LLStyle(const LLStyle::Params& p)
 	mFont(p.font()),
 	mLink(p.link_href),
 	mDropShadow(p.drop_shadow),
-	mImageHeight(0),
-	mImageWidth(0),
 	mImagep(p.image())
 {}
 
@@ -100,9 +98,7 @@ void LLStyle::setImage(const LLUUID& src)
 	mImagep = LLUI::getUIImageByID(src);
 }
 
-
-void LLStyle::setImageSize(S32 width, S32 height)
+void LLStyle::setImage(const std::string& name)
 {
-    mImageWidth = width;
-    mImageHeight = height;
+	mImagep = LLUI::getUIImage(name);
 }
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index dcf274a651346234537bf5a31612dc3b1c72a31d..5e8883afd7f780d64e1ee7570bbcab2e9bb51abe 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -69,9 +69,9 @@ class LLStyle : public LLRefCount
 
 	LLUIImagePtr getImage() const;
 	void setImage(const LLUUID& src);
+	void setImage(const std::string& name);
 
-	BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); }
-	void setImageSize(S32 width, S32 height);
+	BOOL isImage() const { return mImagep.notNull(); }
 
 	// inlined here to make it easier to compare to member data below. -MG
 	bool operator==(const LLStyle &rhs) const
@@ -82,8 +82,6 @@ class LLStyle : public LLRefCount
 			&& mFont == rhs.mFont
 			&& mLink == rhs.mLink
 			&& mImagep == rhs.mImagep
-			&& mImageHeight == rhs.mImageHeight
-			&& mImageWidth == rhs.mImageWidth
 			&& mItalic == rhs.mItalic
 			&& mBold == rhs.mBold
 			&& mUnderline == rhs.mUnderline
@@ -97,8 +95,6 @@ class LLStyle : public LLRefCount
 	BOOL        mBold;
 	BOOL        mUnderline;
 	BOOL		mDropShadow;
-	S32         mImageWidth;
-	S32         mImageHeight;
 
 protected:
 	~LLStyle() { }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..038ea2188f3aca0ea13cfd9ea1399856c9a9ef5b
--- /dev/null
+++ b/indra/llui/lltextbase.cpp
@@ -0,0 +1,451 @@
+/** 
+ * @file lltextbase.cpp
+ * @author Martin Reddy
+ * @brief The base class of text box/editor, providing Url handling support
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltextbase.h"
+#include "llstl.h"
+#include "llview.h"
+#include "llwindow.h"
+#include "llmenugl.h"
+#include "lluictrl.h"
+#include "llurlaction.h"
+#include "llurlregistry.h"
+
+#include <boost/bind.hpp>
+
+// global state for all text fields
+LLUIColor LLTextBase::mLinkColor = LLColor4::blue;
+
+bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const
+{
+	return a->getEnd() < b->getEnd();
+}
+
+//
+// LLTextSegment
+//
+
+LLTextSegment::~LLTextSegment()
+{}
+
+S32	LLTextSegment::getWidth(S32 first_char, S32 num_chars) const { return 0; }
+S32	LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }
+S32	LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; }
+void LLTextSegment::updateLayout(const LLTextBase& editor) {}
+F32	LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; }
+S32	LLTextSegment::getMaxHeight() const { return 0; }
+bool LLTextSegment::canEdit() const { return false; }
+void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
+void LLTextSegment::linkToDocument(LLTextBase*) {}
+void LLTextSegment::setHasMouseHover(bool hover) {}
+const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; }
+void LLTextSegment::setColor(const LLColor4 &color) {}
+const LLStyleSP LLTextSegment::getStyle() const {static LLStyleSP sp(new LLStyle()); return sp; }
+void LLTextSegment::setStyle(const LLStyleSP &style) {}
+void LLTextSegment::setToken( LLKeywordToken* token ) {}
+LLKeywordToken*	LLTextSegment::getToken() const { return NULL; }
+BOOL LLTextSegment::getToolTip( std::string& msg ) const { return FALSE; }
+void LLTextSegment::setToolTip( const std::string &msg ) {}
+void LLTextSegment::dump() const {}
+
+
+//
+// LLNormalTextSegment
+//
+
+LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor ) 
+:	LLTextSegment(start, end),
+	mStyle( style ),
+	mToken(NULL),
+	mHasMouseHover(false),
+	mEditor(editor)
+{
+	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+}
+
+LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible) 
+:	LLTextSegment(start, end),
+	mToken(NULL),
+	mHasMouseHover(false),
+	mEditor(editor)
+{
+	mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
+
+	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+}
+
+F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+{
+	if( end - start > 0 )
+	{
+		if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
+		{
+			LLUIImagePtr image = mStyle->getImage();
+			S32 style_image_height = image->getHeight();
+			S32 style_image_width = image->getWidth();
+			image->draw(draw_rect.mLeft, draw_rect.mTop-style_image_height, 
+				style_image_width, style_image_height);
+		}
+
+		return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect.mLeft, draw_rect.mBottom);
+	}
+	return draw_rect.mLeft;
+}
+
+// Draws a single text segment, reversing the color for selection if needed.
+F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y)
+{
+	const LLWString &text = mEditor.getWText();
+
+	F32 right_x = x;
+	if (!mStyle->isVisible())
+	{
+		return right_x;
+	}
+
+	const LLFontGL* font = mStyle->getFont();
+
+	LLColor4 color = mStyle->getColor();
+
+	font = mStyle->getFont();
+
+  	if( selection_start > seg_start )
+	{
+		// Draw normally
+		S32 start = seg_start;
+		S32 end = llmin( selection_start, seg_end );
+		S32 length =  end - start;
+		font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+	}
+	x = right_x;
+	
+	if( (selection_start < seg_end) && (selection_end > seg_start) )
+	{
+		// Draw reversed
+		S32 start = llmax( selection_start, seg_start );
+		S32 end = llmin( selection_end, seg_end );
+		S32 length = end - start;
+
+		font->render(text, start, x, y,
+					 LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
+					 LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+	}
+	x = right_x;
+	if( selection_end < seg_end )
+	{
+		// Draw normally
+		S32 start = llmax( selection_end, seg_start );
+		S32 end = seg_end;
+		S32 length = end - start;
+		font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+	}
+	return right_x;
+}
+
+S32	LLNormalTextSegment::getMaxHeight() const	
+{ 
+	return mMaxHeight; 
+}
+
+BOOL LLNormalTextSegment::getToolTip(std::string& msg) const
+{
+	// do we have a tooltip for a loaded keyword (for script editor)?
+	if (mToken && !mToken->getToolTip().empty())
+	{
+		const LLWString& wmsg = mToken->getToolTip();
+		msg = wstring_to_utf8str(wmsg);
+		return TRUE;
+	}
+	// or do we have an explicitly set tooltip (e.g., for Urls)
+	if (! mTooltip.empty())
+	{
+		msg = mTooltip;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+void LLNormalTextSegment::setToolTip(const std::string& tooltip)
+{
+	// we cannot replace a keyword tooltip that's loaded from a file
+	if (mToken)
+	{
+		llwarns << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << llendl;
+		return;
+	}
+	mTooltip = tooltip;
+}
+
+S32	LLNormalTextSegment::getWidth(S32 first_char, S32 num_chars) const
+{
+	LLWString text = mEditor.getWText();
+	return mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
+}
+
+S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
+{
+	LLWString text = mEditor.getWText();
+	return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
+											   (F32)segment_local_x_coord,
+											   F32_MAX,
+											   num_chars,
+											   round);
+}
+
+S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+{
+	LLWString text = mEditor.getWText();
+	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart, 
+												(F32)num_pixels,
+												max_chars, 
+												mEditor.getWordWrap());
+
+	if (num_chars == 0 
+		&& line_offset == 0 
+		&& max_chars > 0)
+	{
+		// If at the beginning of a line, and a single character won't fit, draw it anyway
+		num_chars = 1;
+	}
+	if (mStart + segment_offset + num_chars == mEditor.getLength())
+	{
+		// include terminating NULL
+		num_chars++;
+	}
+	return num_chars;
+}
+
+void LLNormalTextSegment::dump() const
+{
+	llinfos << "Segment [" << 
+//			mColor.mV[VX] << ", " <<
+//			mColor.mV[VY] << ", " <<
+//			mColor.mV[VZ] << "]\t[" <<
+		mStart << ", " <<
+		getEnd() << "]" <<
+		llendl;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// LLTextBase
+//
+
+LLTextBase::LLTextBase(const LLUICtrl::Params &p) :
+	mHoverSegment(NULL),
+	mDefaultFont(p.font),
+	mParseHTML(TRUE),
+	mPopupMenu(NULL)
+{
+}
+
+LLTextBase::~LLTextBase()
+{
+	clearSegments();
+}
+
+void LLTextBase::clearSegments()
+{
+	setHoverSegment(NULL);
+	mSegments.clear();
+}
+
+void LLTextBase::setHoverSegment(LLTextSegmentPtr segment)
+{
+	if (mHoverSegment)
+	{
+		mHoverSegment->setHasMouseHover(false);
+	}
+	if (segment)
+	{
+		segment->setHasMouseHover(true);
+	}
+	mHoverSegment = segment;
+}
+
+void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const
+{
+	*seg_iter = getSegIterContaining(startpos);
+	if (*seg_iter == mSegments.end())
+	{
+		*offsetp = 0;
+	}
+	else
+	{
+		*offsetp = startpos - (**seg_iter)->getStart();
+	}
+}
+
+void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp )
+{
+	*seg_iter = getSegIterContaining(startpos);
+	if (*seg_iter == mSegments.end())
+	{
+		*offsetp = 0;
+	}
+	else
+	{
+		*offsetp = startpos - (**seg_iter)->getStart();
+	}
+}
+
+LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
+{
+	segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));
+	return it;
+}
+
+LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 index) const
+{
+	LLTextBase::segment_set_t::const_iterator it =  mSegments.upper_bound(new LLIndexSegment(index));
+	return it;
+}
+
+// Finds the text segment (if any) at the give local screen position
+LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y )
+{
+	// Find the cursor position at the requested local screen position
+	S32 offset = getDocIndexFromLocalCoord( x, y, FALSE );
+	segment_set_t::iterator seg_iter = getSegIterContaining(offset);
+	if (seg_iter != mSegments.end())
+	{
+		return *seg_iter;
+	}
+	else
+	{
+		return LLTextSegmentPtr();
+	}
+}
+
+BOOL LLTextBase::handleHoverOverUrl(S32 x, S32 y)
+{
+	setHoverSegment(NULL);
+
+	// Check to see if we're over an HTML-style link
+	LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
+	if (cur_segment)
+	{
+		setHoverSegment(cur_segment);
+
+		LLStyleSP style =  cur_segment->getStyle();
+		if (style && style->isLink())
+		{
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL LLTextBase::handleMouseUpOverUrl(S32 x, S32 y)
+{
+	if (mParseHTML && mHoverSegment)
+	{
+		LLStyleSP style = mHoverSegment->getStyle();
+		if (style && style->isLink())
+		{
+			LLUrlAction::clickAction(style->getLinkHREF());
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL LLTextBase::handleRightMouseDownOverUrl(LLView *view, S32 x, S32 y)
+{
+	// pop up a context menu for any Url under the cursor
+	const LLTextSegment* cur_segment = getSegmentAtLocalPos(x, y);
+	if (cur_segment && cur_segment->getStyle() && cur_segment->getStyle()->isLink())
+	{
+		delete mPopupMenu;
+		mPopupMenu = createUrlContextMenu(cur_segment->getStyle()->getLinkHREF());
+		if (mPopupMenu)
+		{
+			mPopupMenu->show(x, y);
+			LLMenuGL::showPopup(view, mPopupMenu, x, y);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL LLTextBase::handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+	const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
+	if (cur_segment && cur_segment->getToolTip( msg ) && view)
+	{
+		// Use a slop area around the cursor
+		const S32 SLOP = 8;
+		// Convert rect local to screen coordinates
+		view->localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect_screen->mLeft),
+								 &(sticky_rect_screen->mBottom));
+		sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
+		sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
+	}
+	return TRUE;
+}
+
+LLContextMenu *LLTextBase::createUrlContextMenu(const std::string &in_url)
+{
+	// work out the XUI menu file to use for this url
+	LLUrlMatch match;
+	std::string url = in_url;
+	if (! LLUrlRegistry::instance().findUrl(url, match))
+	{
+		return NULL;
+	}
+	
+	std::string xui_file = match.getMenuName();
+	if (xui_file.empty())
+	{
+		return NULL;
+	}
+
+	// set up the callbacks for all of the potential menu items, N.B. we
+	// don't use const ref strings in callbacks in case url goes out of scope
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url));
+	registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
+	registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
+	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
+	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
+	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
+	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
+
+	// create and return the context menu from the XUI file
+	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
+																		 LLMenuHolderGL::child_registry_t::instance());	
+}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
new file mode 100644
index 0000000000000000000000000000000000000000..27b88761a8bb1bd5b5a133239ef0bcfbd1b0c606
--- /dev/null
+++ b/indra/llui/lltextbase.h
@@ -0,0 +1,198 @@
+/** 
+ * @file lltextbase.h
+ * @author Martin Reddy
+ * @brief The base class of text box/editor, providing Url handling support
+ *
+ * $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_LLTEXTBASE_H
+#define LL_LLTEXTBASE_H
+
+#include "v4color.h"
+#include "llstyle.h"
+#include "llkeywords.h"
+#include "lluictrl.h"
+
+#include <string>
+#include <set>
+
+class LLContextMenu;
+class LLTextSegment;
+
+typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
+
+///
+/// The LLTextBase class provides a base class for all text fields, such
+/// as LLTextEditor and LLTextBox. It implements shared functionality
+/// such as Url highlighting and opening.
+///
+class LLTextBase
+{
+public:
+	LLTextBase(const LLUICtrl::Params &p);
+	virtual ~LLTextBase();
+
+	/// specify the color to display Url hyperlinks in the text
+	static void setLinkColor(LLColor4 color) { mLinkColor = color; }
+
+	/// enable/disable the automatic hyperlinking of Urls in the text
+	void        setParseHTML(BOOL parsing) { mParseHTML=parsing; }
+
+	// public text editing virtual methods
+	virtual LLWString getWText() const = 0;
+	virtual BOOL      allowsEmbeddedItems() const { return FALSE; }
+	virtual BOOL      getWordWrap() { return mWordWrap; }
+	virtual S32       getLength() const = 0;
+
+protected:
+	struct compare_segment_end
+	{
+		bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const;
+	};
+	typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
+
+	// routines to manage segments 
+	void                getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
+	void                getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
+	LLTextSegmentPtr    getSegmentAtLocalPos( S32 x, S32 y );
+	segment_set_t::iterator			getSegIterContaining(S32 index);
+	segment_set_t::const_iterator	getSegIterContaining(S32 index) const;
+	void                clearSegments();
+	void                setHoverSegment(LLTextSegmentPtr segment);
+
+	// event handling for Urls within the text field
+	BOOL                handleHoverOverUrl(S32 x, S32 y);
+	BOOL                handleMouseUpOverUrl(S32 x, S32 y);
+	BOOL                handleRightMouseDownOverUrl(LLView *view, S32 x, S32 y);
+	BOOL                handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
+
+	// pure virtuals that have to be implemented by any subclasses
+	virtual S32         getLineCount() const = 0;
+	virtual S32         getLineStart( S32 line ) const = 0;
+	virtual S32         getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const = 0;
+
+	// protected member variables
+	static LLUIColor    mLinkColor;
+	const LLFontGL      *mDefaultFont;
+	segment_set_t       mSegments;
+	LLTextSegmentPtr    mHoverSegment;	
+	BOOL                mParseHTML;
+	BOOL                mWordWrap;
+
+private:
+	// create a popup context menu for the given Url
+	static LLContextMenu *createUrlContextMenu(const std::string &url);
+
+	LLContextMenu        *mPopupMenu;
+};
+
+///
+/// A text segment is used to specify a subsection of a text string
+/// that should be formatted differently, such as a hyperlink. It
+/// includes a start/end offset from the start of the string, a
+/// style to render with, an optional tooltip, etc.
+///
+class LLTextSegment : public LLRefCount
+{
+public:
+	LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
+	virtual ~LLTextSegment();
+
+	virtual S32					getWidth(S32 first_char, S32 num_chars) const;
+	virtual S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
+	virtual S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+	virtual void				updateLayout(const class LLTextBase& editor);
+	virtual F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+	virtual S32					getMaxHeight() const;
+	virtual bool				canEdit() const;
+	virtual void				unlinkFromDocument(class LLTextBase* editor);
+	virtual void				linkToDocument(class LLTextBase* editor);
+
+	virtual void				setHasMouseHover(bool hover);
+	virtual const LLColor4&		getColor() const;
+	virtual void 				setColor(const LLColor4 &color);
+	virtual const LLStyleSP		getStyle() const;
+	virtual void 				setStyle(const LLStyleSP &style);
+	virtual void				setToken( LLKeywordToken* token );
+	virtual LLKeywordToken*		getToken() const;
+	virtual BOOL				getToolTip( std::string& msg ) const;
+	virtual void				setToolTip(const std::string& tooltip);
+	virtual void				dump() const;
+
+	S32							getStart() const 					{ return mStart; }
+	void						setStart(S32 start)					{ mStart = start; }
+	S32							getEnd() const						{ return mEnd; }
+	void						setEnd( S32 end )					{ mEnd = end; }
+
+protected:
+	S32				mStart;
+	S32				mEnd;
+};
+
+class LLNormalTextSegment : public LLTextSegment
+{
+public:
+	LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor );
+	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+
+	/*virtual*/ S32					getWidth(S32 first_char, S32 num_chars) const;
+	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
+	/*virtual*/ S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+	/*virtual*/ F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+	/*virtual*/ S32					getMaxHeight() const;
+	/*virtual*/ bool				canEdit() const { return true; }
+	/*virtual*/ void				setHasMouseHover(bool hover)		{ mHasMouseHover = hover; }
+	/*virtual*/ const LLColor4&		getColor() const					{ return mStyle->getColor(); }
+	/*virtual*/ void 				setColor(const LLColor4 &color)		{ mStyle->setColor(color); }
+	/*virtual*/ const LLStyleSP		getStyle() const					{ return mStyle; }
+	/*virtual*/ void 				setStyle(const LLStyleSP &style)	{ mStyle = style; }
+	/*virtual*/ void				setToken( LLKeywordToken* token )	{ mToken = token; }
+	/*virtual*/ LLKeywordToken*		getToken() const					{ return mToken; }
+	/*virtual*/ BOOL				getToolTip( std::string& msg ) const;
+	/*virtual*/ void				setToolTip(const std::string& tooltip);
+	/*virtual*/ void				dump() const;
+
+protected:
+	F32				drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y);
+
+	class LLTextBase&	mEditor;
+	LLStyleSP		mStyle;
+	S32				mMaxHeight;
+	LLKeywordToken* mToken;
+	bool			mHasMouseHover;
+	std::string     mTooltip;
+};
+
+class LLIndexSegment : public LLTextSegment
+{
+public:
+	LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
+};
+
+#endif
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 96e72487b85d8af9575a9760cba7a3898ca5f80f..30bf182deb36909bb26d2607be5c8ae614522f94 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -32,30 +32,24 @@
 
 #include "linden_common.h"
 #include "lltextbox.h"
-#include "lllink.h"
 #include "lluictrlfactory.h"
 #include "llfocusmgr.h"
 #include "llwindow.h"
+#include "llurlregistry.h"
+#include "llstyle.h"
 
 static LLDefaultChildRegistry::Register<LLTextBox> r("text");
 
-//*NOTE
-// LLLink is not used in code for now, therefor Visual Studio doesn't build it.
-// "link" is registered here to force Visual Studio to build LLLink class.
-static LLDefaultChildRegistry::Register<LLLink>	register_link("link");
-
 LLTextBox::Params::Params()
 :	text_color("text_color"),
 	length("length"),
 	type("type"),
-	highlight_on_hover("hover", false),
 	border_visible("border_visible", false),
 	border_drop_shadow_visible("border_drop_shadow_visible", false),
 	bg_visible("bg_visible", false),
 	use_ellipses("use_ellipses"),
 	word_wrap("word_wrap", false),
 	drop_shadow_visible("drop_shadow_visible"),
-	hover_color("hover_color"),
 	disabled_color("disabled_color"),
 	background_color("background_color"),
 	border_color("border_color"),
@@ -68,9 +62,7 @@ LLTextBox::Params::Params()
 
 LLTextBox::LLTextBox(const LLTextBox::Params& p)
 :	LLUICtrl(p),
-    mFontGL(p.font),
-	mHoverActive( p.highlight_on_hover ),
-	mHasHover( FALSE ),
+	LLTextBase(p),
 	mBackgroundVisible( p.bg_visible ),
 	mBorderVisible( p.border_visible ),
 	mShadowType( p.font_shadow ),
@@ -84,12 +76,11 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p)
 	mDisabledColor(p.disabled_color()),
 	mBackgroundColor(p.background_color()),
 	mBorderColor(p.border_color()),
-	mHoverColor(p.hover_color()),
 	mHAlign(p.font_halign),
 	mLineSpacing(p.line_spacing),
-	mWordWrap( p.word_wrap ),
 	mDidWordWrap(FALSE)
 {
+	mWordWrap = p.word_wrap;
 	setText( p.text() );
 }
 
@@ -97,9 +88,9 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL	handled = FALSE;
 
-	// HACK: Only do this if there actually is a click callback, so that
+	// HACK: Only do this if there actually is something to click, so that
 	// overly large text boxes in the older UI won't start eating clicks.
-	if (mClickedCallback)
+	if (isClickable())
 	{
 		handled = TRUE;
 
@@ -121,10 +112,9 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
 
 	// We only handle the click if the click both started and ended within us
 
-	// HACK: Only do this if there actually is a click callback, so that
+	// HACK: Only do this if there actually is something to click, so that
 	// overly large text boxes in the older UI won't start eating clicks.
-	if (mClickedCallback
-		&& hasMouseCapture())
+	if (isClickable() && hasMouseCapture())
 	{
 		handled = TRUE;
 
@@ -136,27 +126,44 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
 			make_ui_sound("UISndClickRelease");
 		}
 
-		// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
-		// If mouseup in the widget, it's been clicked
-		if (mClickedCallback)
+		// handle clicks on Urls in the textbox first
+		if (! handleMouseUpOverUrl(x, y))
 		{
-			mClickedCallback();
+			// DO THIS AT THE VERY END to allow the button to be destroyed
+			// as a result of being clicked.  If mouseup in the widget,
+			// it's been clicked
+			if (mClickedCallback && ! handled)
+			{
+				mClickedCallback();
+			}
 		}
 	}
 
 	return handled;
 }
 
+BOOL LLTextBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	// pop up a context menu for any Url under the cursor
+	return handleRightMouseDownOverUrl(this, x, y);
+}
+
 BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
 {
-	BOOL handled = LLView::handleHover(x,y,mask);
-	if(mHoverActive)
+	// Check to see if we're over an HTML-style link
+	if (handleHoverOverUrl(x, y))
 	{
-		mHasHover = TRUE; // This should be set every frame during a hover.
-		getWindow()->setCursor(UI_CURSOR_ARROW);
+		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;		
+		getWindow()->setCursor(UI_CURSOR_HAND);
+		return TRUE;
 	}
 
-	return (handled || mHasHover);
+	return LLView::handleHover(x,y,mask);
+}
+
+BOOL LLTextBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+	return handleToolTipForUrl(this, x, y, msg, sticky_rect_screen);
 }
 
 void LLTextBox::setText(const LLStringExplicit& text)
@@ -168,7 +175,7 @@ void LLTextBox::setText(const LLStringExplicit& text)
 	else
 	{
 		mText.assign(text);
-		setLineLengths();
+		updateDisplayTextAndSegments();
 	}
 }
 
@@ -177,11 +184,11 @@ void LLTextBox::setLineLengths()
 	mLineLengthList.clear();
 	
 	std::string::size_type  cur = 0;
-	std::string::size_type  len = mText.getWString().size();
+	std::string::size_type  len = mDisplayText.size();
 
 	while (cur < len) 
 	{
-		std::string::size_type end = mText.getWString().find('\n', cur);
+		std::string::size_type end = mDisplayText.find('\n', cur);
 		std::string::size_type runLen;
 		
 		if (end == std::string::npos)
@@ -199,20 +206,12 @@ void LLTextBox::setLineLengths()
 	}
 }
 
-void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
+LLWString LLTextBox::wrapText(const LLWString &wtext, S32 &hoffset, S32 &line_num, F32 max_width)
 {
-	if (max_width < 0.0f)
-	{
-		max_width = (F32)getRect().getWidth();
-	}
-
-	LLWString wtext = utf8str_to_wstring(in_text);
 	LLWString final_wtext;
 
-	LLWString::size_type  cur = 0;;
-	LLWString::size_type  len = wtext.size();
-	F32 line_height =  mFontGL->getLineHeight();
-	S32 line_num = 1;
+	LLWString::size_type cur = 0;
+	LLWString::size_type len = wtext.size();
 	while (cur < len)
 	{
 		LLWString::size_type end = wtext.find('\n', cur);
@@ -221,41 +220,121 @@ void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
 			end = len;
 		}
 		
+		bool charsRemaining = true;
 		LLWString::size_type runLen = end - cur;
 		if (runLen > 0)
 		{
+			// work out how many chars can fit onto the current line
 			LLWString run(wtext, cur, runLen);
 			LLWString::size_type useLen =
-				mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE);
+				mDefaultFont->maxDrawableChars(run.c_str(), max_width-hoffset, runLen, TRUE);
+			charsRemaining = (cur + useLen < len);
 
+			// try to break lines on word boundaries
+			if (useLen < run.size())
+			{
+				LLWString::size_type prev_use_len = useLen;
+				while (useLen > 0 && ! isspace(run[useLen-1]) && ! ispunct(run[useLen-1]))
+				{
+					--useLen;
+				}
+				if (useLen == 0)
+				{
+					useLen = prev_use_len;
+				}
+			}
+
+			// add the chars that could fit onto one line to our result
 			final_wtext.append(wtext, cur, useLen);
 			cur += useLen;
-			// not enough room to add any more characters
-			if (useLen == 0) break;
+			hoffset += mDefaultFont->getWidth(run.substr(0, useLen).c_str());
+
+			// abort if not enough room to add any more characters
+			if (useLen == 0)
+			{
+				break;
+			}
 		}
 
-		if (cur < len)
+		if (charsRemaining)
 		{
 			if (wtext[cur] == '\n')
 			{
 				cur += 1;
 			}
-			line_num +=1;
-			// Don't wrap the last line if the text is going to spill off
-			// the bottom of the rectangle.  Assume we prefer to run off
-			// the right edge.
-			// *TODO: Is this the right behavior?
-			if((line_num-1)*line_height <= (F32)getRect().getHeight())
+			final_wtext += '\n';
+			hoffset = 0;
+			line_num += 1;
+		}
+	}
+
+	return final_wtext;
+}
+
+void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
+{
+	mDidWordWrap = TRUE;
+	setText(wstring_to_utf8str(getWrappedText(in_text, max_width)));
+}
+
+LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_width)
+{
+	//
+	// we don't want to wrap Urls otherwise we won't be able to detect their
+	// presence for hyperlinking. So we look for all Urls, and then word wrap
+	// the text before and after, but never break a Url in the middle. We
+	// also need to consider that the Url will be displayed as a label (not
+	// necessary the actual Url string).
+	//
+
+	if (max_width < 0.0f)
+	{
+		max_width = (F32)getRect().getWidth();
+	}
+
+	LLWString wtext = utf8str_to_wstring(in_text);
+	LLWString final_wtext;
+	S32 line_num = 1;
+	S32 hoffset = 0;
+
+	// find the next Url in the text string
+	LLUrlMatch match;
+	while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(wtext), match))
+	{
+		S32 start = match.getStart();
+		S32 end = match.getEnd() + 1;
+
+		// perform word wrap on the text before the Url
+		final_wtext += wrapText(wtext.substr(0, start), hoffset, line_num, max_width);
+
+		// add the Url (but compute width based on its label)
+		S32 label_width = mDefaultFont->getWidth(match.getLabel());
+		if (hoffset > 0 && hoffset + label_width > max_width)
+		{
+			final_wtext += '\n';
+			line_num++;
+			hoffset = 0;
+		}
+		final_wtext += wtext.substr(start, end-start);
+		hoffset += label_width;
+		if (hoffset > max_width)
+		{
+			final_wtext += '\n';
+			line_num++;
+			hoffset = 0;
+			// eat any leading whitespace on the next line
+			while (isspace(wtext[end]) && end < (S32)wtext.size())
 			{
-				final_wtext += '\n';
+				end++;
 			}
 		}
+
+		// move on to the rest of the text after the Url
+		wtext = wtext.substr(end, wtext.size() - end + 1);
 	}
-	
-	mDidWordWrap = TRUE;
-	std::string final_text = wstring_to_utf8str(final_wtext);
-	setText(final_text);
 
+	final_wtext += wrapText(wtext, hoffset, line_num, max_width);
+	return final_wtext;
 }
 
 S32 LLTextBox::getTextPixelWidth()
@@ -268,7 +347,7 @@ S32 LLTextBox::getTextPixelWidth()
 			iter != mLineLengthList.end(); ++iter)
 		{
 			S32 line_length = *iter;
-			S32 line_width = mFontGL->getWidth( mText.getWString().c_str(), cur_pos, line_length );
+			S32 line_width = mDefaultFont->getWidth( mDisplayText.c_str(), cur_pos, line_length );
 			if( line_width > max_line_width )
 			{
 				max_line_width = line_width;
@@ -278,7 +357,7 @@ S32 LLTextBox::getTextPixelWidth()
 	}
 	else
 	{
-		max_line_width = mFontGL->getWidth(mText.getWString().c_str());
+		max_line_width = mDefaultFont->getWidth(mDisplayText.c_str());
 	}
 	return max_line_width;
 }
@@ -290,7 +369,7 @@ S32 LLTextBox::getTextPixelHeight()
 	{
 		num_lines = 1;
 	}
-	return (S32)(num_lines * mFontGL->getLineHeight());
+	return (S32)(num_lines * mDefaultFont->getLineHeight());
 }
 
 void LLTextBox::setValue(const LLSD& value )
@@ -302,7 +381,7 @@ void LLTextBox::setValue(const LLSD& value )
 BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
 {
 	mText.setArg(key, text);
-	setLineLengths();
+	updateDisplayTextAndSegments();
 	return TRUE;
 }
 
@@ -345,18 +424,11 @@ void LLTextBox::draw()
 
 	if ( getEnabled() )
 	{
-		if(mHasHover)
-		{
-			drawText( text_x, text_y, mHoverColor.get() );
-		}
-		else
-		{
-			drawText( text_x, text_y, mTextColor.get() );
-		}				
+		drawText( text_x, text_y, mDisplayText, mTextColor.get() );
 	}
 	else
 	{
-		drawText( text_x, text_y, mDisabledColor.get() );
+		drawText( text_x, text_y, mDisplayText, mDisabledColor.get() );
 	}
 
 	if (sDebugRects)
@@ -370,41 +442,49 @@ void LLTextBox::draw()
 	//{
 	//	drawDebugRect();
 	//}
-
-	mHasHover = FALSE; // This is reset every frame.
 }
 
 void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	// reparse line lengths
+	// reparse line lengths (don't need to recalculate the display text)
 	setLineLengths();
 	LLView::reshape(width, height, called_from_parent);
 }
 
-void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
+void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& color )
 {
-	if( mLineLengthList.empty() )
+	if (mSegments.size() > 1)
 	{
-		mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color,
-						mHAlign, mVAlign, 
-						0,
-						mShadowType,
-						S32_MAX, getRect().getWidth(), NULL, mUseEllipses);
+		// we have Urls (or other multi-styled segments)
+		drawTextSegments(x, y, text);
+	}
+	else if( mLineLengthList.empty() )
+	{
+		// simple case of 1 line of text in one style
+		mDefaultFont->render(text, 0, (F32)x, (F32)y, color,
+							 mHAlign, mVAlign, 
+							 0,
+							 mShadowType,
+							 S32_MAX, getRect().getWidth(), NULL, mUseEllipses);
 	}
 	else
 	{
+		// simple case of multiple lines of text, all in the same style
 		S32 cur_pos = 0;
 		for (std::vector<S32>::iterator iter = mLineLengthList.begin();
 			iter != mLineLengthList.end(); ++iter)
 		{
 			S32 line_length = *iter;
-			mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color,
-							mHAlign, mVAlign,
-							0,
-							mShadowType,
-							line_length, getRect().getWidth(), NULL, mUseEllipses );
+			mDefaultFont->render(text, cur_pos, (F32)x, (F32)y, color,
+								 mHAlign, mVAlign,
+								 0,
+								 mShadowType,
+								 line_length, getRect().getWidth(), NULL, mUseEllipses );
 			cur_pos += line_length + 1;
-			y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
+			S32 line_height = llfloor(mDefaultFont->getLineHeight()) + mLineSpacing; 
+			y -= line_height;
+			if(y < line_height)
+				break;
 		}
 	}
 }
@@ -415,3 +495,254 @@ void LLTextBox::reshapeToFitText()
 	S32 height = getTextPixelHeight();
 	reshape( width + 2 * mHPad, height + 2 * mVPad );
 }
+
+S32 LLTextBox::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
+{
+	// Returns the character offset for the character under the local (x, y) coordinate.
+	// When round is true, if the position is on the right half of a character, the cursor
+	// will be put to its right.  If round is false, the cursor will always be put to the
+	// character's left.
+
+	LLRect rect = getLocalRect();
+	rect.mLeft += mHPad;
+	rect.mRight -= mHPad;
+	rect.mTop += mVPad;
+	rect.mBottom -= mVPad;
+
+	// Figure out which line we're nearest to.
+	S32 total_lines = getLineCount();
+	S32 line_height = llround( mDefaultFont->getLineHeight() ) + mLineSpacing;
+	S32 line = (rect.mTop - 1 - local_y) / line_height;
+	if (line >= total_lines)
+	{
+		return getLength(); // past the end
+	}
+
+	line = llclamp( line, 0, total_lines );
+	S32 line_start = getLineStart(line);
+	S32 next_start = getLineStart(line+1);
+	S32	line_end = (next_start != line_start) ? next_start - 1 : getLength();
+	if (line_start == -1)
+	{
+		return 0;
+	}
+
+	S32 line_len = line_end - line_start;
+	S32 pos = mDefaultFont->charFromPixelOffset(mDisplayText.c_str(), line_start,
+												(F32)(local_x - rect.mLeft),
+												(F32)rect.getWidth(),
+												line_len, round);
+
+	return line_start + pos;
+}
+
+S32 LLTextBox::getLineStart( S32 line ) const
+{
+	line = llclamp(line, 0, getLineCount()-1);
+
+	S32 result = 0;
+	for (int i = 0; i < line; i++)
+	{
+		result += mLineLengthList[i] + 1 /* add newline */;
+	}
+
+	return result;
+}
+
+void LLTextBox::updateDisplayTextAndSegments()
+{
+	// remove any previous segment list
+	clearSegments();
+
+	// if URL parsing is turned off, then not much to bo
+	if (! mParseHTML)
+	{
+		mDisplayText = mText.getWString();
+		setLineLengths();
+		return;
+	}
+
+	// create unique text segments for Urls
+	mDisplayText.clear();
+	S32 end = 0;
+	LLUrlMatch match;
+	LLWString text = mText.getWString();
+		
+	// find the next Url in the text string
+	while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(text), match,
+											  boost::bind(&LLTextBox::onUrlLabelUpdated, this, _1, _2)) )
+	{
+		// work out the char offset for the start/end of the url
+		S32 seg_start = mDisplayText.size();
+		S32 start = seg_start + match.getStart();
+		end = start + match.getLabel().size();
+
+		// create a segment for the text before the Url
+		mSegments.insert(new LLNormalTextSegment(new LLStyle(), seg_start, start, *this));
+		mDisplayText += text.substr(0, match.getStart());
+
+		// create a segment for the Url text
+		LLStyleSP html(new LLStyle);
+		html->setVisible(true);
+		html->setColor(mLinkColor);
+		html->mUnderline = TRUE;
+		html->setLinkHREF(match.getUrl());
+
+		LLNormalTextSegment *html_seg = new LLNormalTextSegment(html, start, end, *this); 
+		html_seg->setToolTip(match.getTooltip());
+
+		mSegments.insert(html_seg);
+		mDisplayText += utf8str_to_wstring(match.getLabel());
+
+		// move on to the rest of the text after the Url
+		text = text.substr(match.getEnd()+1, text.size() - match.getEnd());
+	}
+
+	// output a segment for the remaining text
+	if (text.size() > 0)
+	{
+		mSegments.insert(new LLNormalTextSegment(new LLStyle(), end, end + text.size(), *this));
+		mDisplayText += text;
+	}
+
+	// strip whitespace from the end of the text
+	while (mDisplayText.size() > 0 && isspace(mDisplayText[mDisplayText.size()-1]))
+	{
+		mDisplayText = mDisplayText.substr(0, mDisplayText.size() - 1);
+
+		segment_set_t::iterator it = getSegIterContaining(mDisplayText.size());
+		if (it != mSegments.end())
+		{
+			LLTextSegmentPtr seg = *it;
+			seg->setEnd(seg->getEnd()-1);
+		}
+	}
+
+	// we may have changed the line lengths, so recalculate them
+	setLineLengths();
+}
+
+void LLTextBox::onUrlLabelUpdated(const std::string &url, const std::string &label)
+{
+	if (mDidWordWrap)
+	{
+		// re-word wrap as the url label lengths may have changed
+		setWrappedText(mText.getString());
+	}
+	else
+	{
+		// or just update the display text with the latest Url labels
+		updateDisplayTextAndSegments();
+	}
+}
+
+bool LLTextBox::isClickable() const
+{
+	// return true if we have been given a click callback
+	if (mClickedCallback)
+	{
+		return true;
+	}
+
+	// also return true if we have a clickable Url in the text
+	segment_set_t::const_iterator it;
+	for (it = mSegments.begin(); it != mSegments.end(); ++it)
+	{
+		LLTextSegmentPtr segmentp = *it;
+		if (segmentp)
+		{
+			const LLStyleSP style = segmentp->getStyle();
+			if (style && style->isLink())
+			{
+				return true;
+			}
+		}
+	}
+
+	// otherwise there is nothing clickable here
+	return false;
+}
+
+void LLTextBox::drawTextSegments(S32 init_x, S32 init_y, const LLWString &text)
+{
+	const S32 text_len = text.length();
+	if (text_len <= 0)
+	{
+		return;
+	}
+
+	S32 cur_line = 0;
+	S32 num_lines = getLineCount();
+	S32 line_start = getLineStart(cur_line);
+	S32 line_height = llround( mDefaultFont->getLineHeight() ) + mLineSpacing;
+	F32 text_y = (F32) init_y;
+	segment_set_t::iterator cur_seg = mSegments.begin();
+
+	// render a line of text at a time
+	const LLRect textRect = getLocalRect();
+	while((textRect.mBottom <= text_y) && (cur_line < num_lines))
+	{
+		S32 next_start = -1;
+		S32 line_end = text_len;
+
+		if ((cur_line + 1) < num_lines)
+		{
+			next_start = getLineStart(cur_line + 1);
+			line_end = next_start;
+		}
+		if ( text[line_end-1] == '\n' )
+		{
+			--line_end;
+		}
+		
+		// render all segments on this line
+		F32 text_x = init_x;
+		S32 seg_start = line_start;
+		while (seg_start < line_end && cur_seg != mSegments.end())
+		{
+			// move to the next segment (or continue the previous one)
+			LLTextSegment *cur_segment = *cur_seg;
+			while (cur_segment->getEnd() <= seg_start)
+			{
+				if (++cur_seg == mSegments.end())
+				{
+					return;
+				}
+				cur_segment = *cur_seg;
+			}
+
+			// Draw a segment within the line
+			S32 clipped_end	= llmin( line_end, cur_segment->getEnd() );
+			S32 clipped_len = clipped_end - seg_start;
+			if( clipped_len > 0 )
+			{
+				LLStyleSP style = cur_segment->getStyle();
+				if (style && style->isVisible())
+				{
+					// work out the color for the segment
+					LLColor4 color ;
+					if (getEnabled())
+					{
+						color = style->isLink() ? mLinkColor.get() : mTextColor.get();
+					}
+					else
+					{
+						color = mDisabledColor.get();
+					}
+
+					// render a single line worth for this segment
+					mDefaultFont->render(text, seg_start, text_x, text_y, color,
+										 mHAlign, mVAlign, 0, mShadowType, clipped_len,
+										 textRect.getWidth(), &text_x, mUseEllipses);
+				}
+
+				seg_start += clipped_len;
+			}
+		}
+
+		// move down one line
+		text_y -= (F32)line_height;
+		line_start = next_start;
+		cur_line++;
+	}
+}
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index d807fe7639425a3cdd5b4a45c3024e940c2dafb8..940b82000409be4ea77be955681e941316480954 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -37,10 +37,11 @@
 #include "v4color.h"
 #include "llstring.h"
 #include "lluistring.h"
+#include "lltextbase.h"
 
-
-class LLTextBox
-:	public LLUICtrl
+class LLTextBox :
+	public LLTextBase,
+	public LLUICtrl
 {
 public:
 	
@@ -51,8 +52,7 @@ class LLTextBox
 	{
 		Optional<std::string> text;
 
-		Optional<bool>		highlight_on_hover,
-							border_visible,
+		Optional<bool>		border_visible,
 							border_drop_shadow_visible,
 							bg_visible,
 							use_ellipses,
@@ -65,7 +65,6 @@ class LLTextBox
 							length;
 
 		Optional<LLUIColor>	text_color,
-							hover_color,
 							disabled_color,
 							background_color,
 							border_color;
@@ -90,15 +89,14 @@ class LLTextBox
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
+	virtual BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
+	virtual BOOL	handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
 
 	void			setColor( const LLColor4& c )			{ mTextColor = c; }
 	void			setDisabledColor( const LLColor4& c)	{ mDisabledColor = c; }
 	void			setBackgroundColor( const LLColor4& c)	{ mBackgroundColor = c; }	
 	void			setBorderColor( const LLColor4& c)		{ mBorderColor = c; }	
 
-	void			setHoverColor( const LLColor4& c )		{ mHoverColor = c; }
-	void			setHoverActive( BOOL active )			{ mHoverActive = active; }
-
 	void			setText( const LLStringExplicit& text );
 	void			setWrappedText(const LLStringExplicit& text, F32 max_width = -1.f); // -1 means use existing control width
 	void			setUseEllipses( BOOL use_ellipses )		{ mUseEllipses = use_ellipses; }
@@ -112,35 +110,42 @@ class LLTextBox
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); }		// mouse down and up within button
 
-	const LLFontGL* getFont() const							{ return mFontGL; }
+	const LLFontGL* getFont() const							{ return mDefaultFont; }
 
 	void			reshapeToFitText();
 
 	const std::string&	getText() const							{ return mText.getString(); }
+	LLWString		getWText() const { return mDisplayText; }
 	S32				getTextPixelWidth();
 	S32				getTextPixelHeight();
+	S32				getLength() const { return mDisplayText.length(); }
 
 	virtual void	setValue(const LLSD& value );		
 	virtual LLSD	getValue() const						{ return LLSD(getText()); }
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 
-private:
+protected:
+	S32 			getLineCount() const { return mLineLengthList.size(); }
+	S32 			getLineStart( S32 line ) const;
+	S32             getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
+	LLWString       getWrappedText(const LLStringExplicit& in_text, F32 max_width = -1.f);
 	void			setLineLengths();
-	void			drawText(S32 x, S32 y, const LLColor4& color );
+	void			updateDisplayTextAndSegments();
+	virtual void	drawText(S32 x, S32 y, const LLWString &text, const LLColor4& color );
+	void            onUrlLabelUpdated(const std::string &url, const std::string &label);
+	bool            isClickable() const;
+	LLWString       wrapText(const LLWString &wtext, S32 &hoffset, S32 &line_num, F32 max_width);
+	void            drawTextSegments(S32 x, S32 y, const LLWString &text);
 
 	LLUIString		mText;
-	const LLFontGL*	mFontGL;
-	LLUIColor	mTextColor;
-	LLUIColor	mDisabledColor;
-	LLUIColor	mBackgroundColor;
-	LLUIColor	mBorderColor;
-	LLUIColor	mHoverColor;
-
-	BOOL			mHoverActive;	
-	BOOL			mHasHover;
+	LLWString		mDisplayText;
+	LLUIColor		mTextColor;
+	LLUIColor		mDisabledColor;
+	LLUIColor		mBackgroundColor;
+	LLUIColor		mBorderColor;
+
 	BOOL			mBackgroundVisible;
 	BOOL			mBorderVisible;
-	BOOL			mWordWrap;
 	BOOL            mDidWordWrap;
 	
 	LLFontGL::ShadowType mShadowType;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 921041d17fe7592ab8af1b6560658b71ea35c607..51c259ff536057fc067ded9bdfdfe85256f35795 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -59,6 +59,7 @@
 #include "lltextparser.h"
 #include "llscrollcontainer.h"
 #include "llpanel.h"
+#include "llurlregistry.h"
 
 #include <queue>
 #include "llcombobox.h"
@@ -78,10 +79,6 @@ const S32	CURSOR_THICKNESS = 2;
 const S32	SPACES_PER_TAB = 4;
 
 
-void (* LLTextEditor::sURLcallback)(const std::string&)   = NULL;
-bool (* LLTextEditor::sSecondlifeURLcallback)(const std::string&)   = NULL;
-bool (* LLTextEditor::sSecondlifeURLcallbackRightClick)(const std::string&)   = NULL;
-
 // helper functors
 struct LLTextEditor::compare_bottom
 {
@@ -331,8 +328,9 @@ LLTextEditor::Params::Params()
 	is_unicode("is_unicode")// ignored
 {}
 
-LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
-	:	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
+LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
+	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
+	LLTextBase(p),
 	mMaxTextByteLength( p.max_text_length ),
 	mBaseDocIsPristine(TRUE),
 	mPristineCmd( NULL ),
@@ -351,7 +349,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 	mFocusBgColor(		p.bg_focus_color() ),
 	mLinkColor(			p.link_color() ),
 	mReadOnly(p.read_only),
-	mWordWrap( p.word_wrap ),
 	mShowLineNumbers ( p.show_line_numbers ),
 	mCommitOnFocusLost( p.commit_on_focus_lost),
 	mTrackBottom( p.track_bottom ),
@@ -363,14 +360,16 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 	mReflowNeeded(FALSE),
 	mScrollNeeded(FALSE),
 	mLastSelectionY(-1),
-	mParseHTML(FALSE),
 	mParseHighlights(FALSE),
 	mTabsToNextField(p.ignore_tab),
-	mDefaultFont(p.font),
 	mScrollIndex(-1)
 {
 	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 
+	mWordWrap = p.word_wrap;
+	mDefaultFont = p.font;
+	mParseHTML = FALSE;
+
 	mSourceID.generate();
 
 	// reset desired x cursor position
@@ -413,7 +412,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 
 	appendText(p.default_text, FALSE, FALSE);
 
-	mHTML.clear();
 }
 
 void LLTextEditor::initFromParams( const LLTextEditor::Params& p)
@@ -451,7 +449,6 @@ LLTextEditor::~LLTextEditor()
 	}
 
 	// Scrollbar is deleted by LLView
-	mHoverSegment = NULL;
 	std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
 }
 
@@ -666,18 +663,12 @@ BOOL LLTextEditor::truncate()
 	return did_truncate;
 }
 
-void LLTextEditor::clearSegments()
-{
-	mHoverSegment = NULL;
-	mSegments.clear();
-}
-
 void LLTextEditor::setText(const LLStringExplicit &utf8str)
 {
+	// clear out the existing text and segments
 	clearSegments();
 
-	// LLStringUtil::removeCRLF(utf8str);
-	getViewModel()->setValue(utf8str_removeCRLF(utf8str));
+	getViewModel()->setValue("");
 
 	truncate();
 	blockUndo();
@@ -687,6 +678,11 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str)
 	startOfDoc();
 	deselect();
 
+	// append the new text (supports Url linking)
+	std::string text(utf8str);
+	LLStringUtil::removeCRLF(text);
+	appendStyledText(text, false, false, LLStyle::Params());
+
 	needsReflow();
 
 	resetDirty();
@@ -696,9 +692,10 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str)
 
 void LLTextEditor::setWText(const LLWString &wtext)
 {
+	// clear out the existing text and segments
 	clearSegments();
 
-	getViewModel()->setDisplay(wtext);
+	getViewModel()->setDisplay(LLWString());
 
 	truncate();
 	blockUndo();
@@ -708,6 +705,9 @@ void LLTextEditor::setWText(const LLWString &wtext)
 	startOfDoc();
 	deselect();
 
+	// append the new text (supports Url linking)
+	appendStyledText(wstring_to_utf8str(wtext), false, false, LLStyle::Params());
+
 	needsReflow();
 
 	resetDirty();
@@ -913,32 +913,6 @@ void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp, boo
 	}
 }
 
-void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const
-{
-	*seg_iter = getSegIterContaining(startpos);
-	if (*seg_iter == mSegments.end())
-	{
-		*offsetp = 0;
-	}
-	else
-	{
-		*offsetp = startpos - (**seg_iter)->getStart();
-	}
-}
-
-void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp )
-{
-	*seg_iter = getSegIterContaining(startpos);
-	if (*seg_iter == mSegments.end())
-	{
-		*offsetp = 0;
-	}
-	else
-	{
-		*offsetp = startpos - (**seg_iter)->getStart();
-	}
-}
-
 const LLTextSegmentPtr	LLTextEditor::getPreviousSegment() const
 {
 	// find segment index at character to left of cursor (or rightmost edge of selection)
@@ -1154,6 +1128,10 @@ S32 LLTextEditor::getEditableIndex(S32 index, bool increasing_direction)
 	segment_set_t::iterator segment_iter;
 	S32 offset;
 	getSegmentAndOffset(index, &segment_iter, &offset);
+	if (segment_iter == mSegments.end())
+	{
+		return 0;
+	}
 
 	LLTextSegmentPtr segmentp = *segment_iter;
 
@@ -1377,25 +1355,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_
 		}
 	}
 
-	const LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y );
-	if( cur_segment )
-	{
-		BOOL has_tool_tip = FALSE;
-		has_tool_tip = cur_segment->getToolTip( msg );
-
-		if( has_tool_tip )
-		{
-			// Just use a slop area around the cursor
-			// Convert rect local to screen coordinates
-			S32 SLOP = 8;
-			localPointToScreen( 
-				x - SLOP, y - SLOP, 
-				&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
-			sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
-			sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
-		}
-	}
-	return TRUE;
+	return handleToolTipForUrl(this, x, y, msg, sticky_rect_screen);
 }
 
 BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1480,12 +1440,6 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
 	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 	BOOL handled = FALSE;
 
-	if (mHoverSegment) 
-	{
-		mHoverSegment->setHasMouseHover(false);
-	}
-	mHoverSegment = NULL;
-
 	if(hasMouseCapture() )
 	{
 		if( mIsSelecting ) 
@@ -1525,30 +1479,11 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
 	if( !handled )
 	{
 		// Check to see if we're over an HTML-style link
-		LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y );
-		if( cur_segment )
+		handled = handleHoverOverUrl(x, y);
+		if( handled )
 		{
-			if(cur_segment->getStyle()->isLink())
-			{
-				lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;		
-				getWindow()->setCursor(UI_CURSOR_HAND);
-				handled = TRUE;
-			}
-			//else
-			//if(cur_segment->getStyle()->getIsEmbeddedItem())
-			//{
-			//	lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;		
-			//	getWindow()->setCursor(UI_CURSOR_HAND);
-			//	//getWindow()->setCursor(UI_CURSOR_ARROW);
-			//	handled = TRUE;
-			//}
-			if (mHoverSegment) 
-			{
-				mHoverSegment->setHasMouseHover(false);
-			}
-			cur_segment->setHasMouseHover(true);
-			mHoverSegment = cur_segment;
-			mHTML = mHoverSegment->getStyle()->getLinkHREF();
+			lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;		
+			getWindow()->setCursor(UI_CURSOR_HAND);
 		}
 
 		if( !handled )
@@ -1581,9 +1516,9 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
 			endSelection();
 		}
 		
-		if( !hasSelection() )
+		if( !hasSelection() && hasMouseCapture() )
 		{
-			handleMouseUpOverSegment( x, y, mask );
+			handleMouseUpOverUrl(x, y);
 		}
 
 		// take selection to 'primary' clipboard
@@ -3477,11 +3412,8 @@ void LLTextEditor::endOfDoc()
 // Sets the scrollbar from the cursor position
 void LLTextEditor::updateScrollFromCursor()
 {
-	if (mReadOnly)
-	{
-		// no cursor in read only mode
-		return;
-	}
+	// Update scroll position even in read-only mode (when there's no cursor displayed)
+	// because startOfDoc()/endOfDoc() modify cursor position. See EXT-736.
 
 	if (!mScrollNeeded)
 	{
@@ -3596,14 +3528,20 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
 	{
 
 		S32 start=0,end=0;
+		LLUrlMatch match;
 		std::string text = new_text;
-		while ( findHTML(text, &start, &end) )
+		while ( LLUrlRegistry::instance().findUrl(text, match,
+		        boost::bind(&LLTextEditor::onUrlLabelUpdated, this, _1, _2)) )
 		{
+			start = match.getStart();
+			end = match.getEnd()+1;
+
 			LLStyle::Params link_params = style_params;
 			link_params.color = mLinkColor;
 			link_params.font.style = "UNDERLINE";
-			link_params.link_href = text.substr(start,end-start);
+			link_params.link_href = match.getUrl();
 
+			// output the text before the Url
 			if (start > 0)
 			{
 				if (part == (S32)LLTextParser::WHOLE ||
@@ -3617,9 +3555,38 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
 				}
 				std::string subtext=text.substr(0,start);
 				appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params); 
+				prepend_newline = false;
 			}
-			
-			appendText(text.substr(start, end-start),allow_undo, prepend_newline, link_params);
+
+			// output the styled Url
+			appendText(match.getLabel(),allow_undo, prepend_newline, link_params);
+			prepend_newline = false;
+
+			// set the tooltip for the Url label
+			if (! match.getTooltip().empty())
+			{
+				segment_set_t::iterator it = getSegIterContaining(getLength()-1);
+				if (it != mSegments.end())
+				{
+					LLTextSegmentPtr segment = *it;
+					segment->setToolTip(match.getTooltip());
+				}
+			}
+
+			// output an optional icon after the Url
+			if (! match.getIcon().empty())
+			{
+				LLUIImagePtr image = LLUI::getUIImage(match.getIcon());
+				if (image)
+				{
+					LLStyle::Params icon;
+					icon.image = image;
+					// TODO: fix spacing of images and remove the fixed char spacing
+					appendText("  ", allow_undo, prepend_newline, icon);
+				}
+			}
+
+			// move on to the rest of the text after the Url
 			if (end < (S32)text.length()) 
 			{
 				text = text.substr(end,text.length() - end);
@@ -3711,7 +3678,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
 	}
 
 	append(wide_text, TRUE, segmentp);
-	
+
 	needsReflow();
 	
 	// Set the cursor and scroll position
@@ -3795,6 +3762,58 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text,
 	}
 }
 
+void LLTextEditor::onUrlLabelUpdated(const std::string &url,
+									 const std::string &label)
+{
+	// LLUrlRegistry has given us a new label for one of our Urls
+	replaceUrlLabel(url, label);
+}
+
+void LLTextEditor::replaceUrlLabel(const std::string &url,
+								   const std::string &label)
+{
+	// get the full (wide) text for the editor so we can change it
+	LLWString text = getWText();
+	LLWString wlabel = utf8str_to_wstring(label);
+	bool modified = false;
+	S32 seg_start = 0;
+
+	// iterate through each segment looking for ones styled as links
+	segment_set_t::iterator it;
+	for (it = mSegments.begin(); it != mSegments.end(); ++it)
+	{
+		LLTextSegment *seg = *it;
+		const LLStyleSP style = seg->getStyle();
+
+		// update segment start/end length in case we replaced text earlier
+		S32 seg_length = seg->getEnd() - seg->getStart();
+		seg->setStart(seg_start);
+		seg->setEnd(seg_start + seg_length);
+
+		// if we find a link with our Url, then replace the label
+		if (style->isLink() && style->getLinkHREF() == url)
+		{
+			S32 start = seg->getStart();
+			S32 end = seg->getEnd();
+			text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1);
+			seg->setEnd(start + wlabel.size());
+			modified = true;
+		}
+
+		// work out the character offset for the next segment
+		seg_start = seg->getEnd();
+	}
+
+	// update the editor with the new (wide) text string
+	if (modified)
+	{
+		getViewModel()->setDisplay(text);
+		deselect();
+		setCursorPos(mCursorPos);
+		needsReflow();
+	}
+}
+
 void LLTextEditor::removeTextFromEnd(S32 num_chars)
 {
 	if (num_chars <= 0) return;
@@ -4097,7 +4116,7 @@ void LLTextEditor::updateSegments()
 		segment_vec_t segment_list;
 		mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
 
-		mSegments.clear();
+		clearSegments();
 		segment_set_t::iterator insert_it = mSegments.begin();
 		for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
 		{
@@ -4106,7 +4125,29 @@ void LLTextEditor::updateSegments()
 	}
 
 	createDefaultSegment();
+}
 
+void LLTextEditor::updateLinkSegments()
+{
+	// update any segments that contain a link
+	for (segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); ++it)
+	{
+		LLTextSegment *segment = *it;
+		if (segment && segment->getStyle() && segment->getStyle()->isLink())
+		{
+			// if the link's label (what the user can edit) is a valid Url,
+			// then update the link's HREF to be the same as the label text.
+			// This lets users edit Urls in-place.
+			LLUrlMatch match;
+			LLStyleSP style = static_cast<LLStyleSP>(segment->getStyle());
+			std::string url_label = getText().substr(segment->getStart(), segment->getEnd()-segment->getStart());
+			if (LLUrlRegistry::instance().findUrl(url_label, match))
+			{
+				LLStringUtil::trim(url_label);
+				style->setLinkHREF(url_label);
+			}
+		}
+	}
 }
 
 void LLTextEditor::insertSegment(LLTextSegmentPtr segment_to_insert)
@@ -4170,57 +4211,6 @@ void LLTextEditor::insertSegment(LLTextSegmentPtr segment_to_insert)
 	}
 }
 
-BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
-{
-	if ( hasMouseCapture() )
-	{
-		// This mouse up was part of a click.
-		// Regardless of where the cursor is, see if we recently touched a link
-		// and launch it if we did.
-		if (mParseHTML && mHTML.length() > 0)
-		{
-				//Special handling for slurls
-			if ( (sSecondlifeURLcallback!=NULL) && !(*sSecondlifeURLcallback)(mHTML) )
-			{
-				if (sURLcallback!=NULL) (*sURLcallback)(mHTML);
-			}
-			mHTML.clear();
-		}
-	}
-
-	return FALSE;
-}
-
-
-// Finds the text segment (if any) at the give local screen position
-LLTextSegmentPtr LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y )
-{
-	// Find the cursor position at the requested local screen position
-	S32 offset = getDocIndexFromLocalCoord( x, y, FALSE );
-	segment_set_t::iterator seg_iter = getSegIterContaining(offset);
-	if (seg_iter != mSegments.end())
-	{
-		return *seg_iter;
-	}
-	else
-	{
-		return LLTextSegmentPtr();
-	}
-}
-
-LLTextEditor::segment_set_t::iterator LLTextEditor::getSegIterContaining(S32 index)
-{
-	segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));
-	return it;
-}
-
-LLTextEditor::segment_set_t::const_iterator LLTextEditor::getSegIterContaining(S32 index) const
-{
-	LLTextEditor::segment_set_t::const_iterator it =  mSegments.upper_bound(new LLIndexSegment(index));
-	return it;
-}
-
-
 void LLTextEditor::onMouseCaptureLost()
 {
 	endSelection();
@@ -4330,169 +4320,6 @@ BOOL LLTextEditor::exportBuffer(std::string &buffer )
 	return TRUE;
 }
 
-///////////////////////////////////////////////////////////////////
-// Refactoring note: We may eventually want to replace this with boost::regex or 
-// boost::tokenizer capabilities since we've already fixed at least two JIRAs
-// concerning logic issues associated with this function.
-S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const
-{
-	std::string openers=" \t\n('\"[{<>";
-	std::string closers=" \t\n)'\"]}><;";
-
-	if (reverse)
-	{
-		for (int index=pos; index >= 0; index--)
-		{
-			char c = line[index];
-			S32 m2 = openers.find(c);
-			if (m2 >= 0)
-			{
-				return index+1;
-			}
-		}
-		return 0; // index is -1, don't want to return that. 
-	} 
-	else
-	{
-		// adjust the search slightly, to allow matching parenthesis inside the URL
-		S32 paren_count = 0;
-		for (int index=pos; index<(S32)line.length(); index++)
-		{
-			char c = line[index];
-
-			if (c == '(')
-			{
-				paren_count++;
-			}
-			else if (c == ')')
-			{
-				if (paren_count <= 0)
-				{
-					return index;
-				}
-				else
-				{
-					paren_count--;
-				}
-			}
-			else
-			{
-				S32 m2 = closers.find(c);
-				if (m2 >= 0)
-				{
-					return index;
-				}
-			}
-		} 
-		return line.length();
-	}		
-}
-
-BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const
-{
-	  
-	S32 m1,m2,m3;
-	BOOL matched = FALSE;
-	
-	m1=line.find("://",*end);
-	
-	if (m1 >= 0) //Easy match.
-	{
-		*begin = findHTMLToken(line, m1, TRUE);
-		*end   = findHTMLToken(line, m1, FALSE);
-		
-		//Load_url only handles http and https so don't hilite ftp, smb, etc.
-		m2 = line.substr(*begin,(m1 - *begin)).find("http");
-		m3 = line.substr(*begin,(m1 - *begin)).find("secondlife");
-	
-		std::string badneighbors=".,<>?';\"][}{=-+_)(*&^%$#@!~`\t\r\n\\";
-	
-		if (m2 >= 0 || m3>=0)
-		{
-			S32 bn = badneighbors.find(line.substr(m1+3,1));
-			
-			if (bn < 0)
-			{
-				matched = TRUE;
-			}
-		}
-	}
-/*	matches things like secondlife.com (no http://) needs a whitelist to really be effective.
-	else	//Harder match.
-	{
-		m1 = line.find(".",*end);
-		
-		if (m1 >= 0)
-		{
-			*end   = findHTMLToken(line, m1, FALSE);
-			*begin = findHTMLToken(line, m1, TRUE);
-			
-			m1 = line.rfind(".",*end);
-
-			if ( ( *end - m1 ) > 2 && m1 > *begin)
-			{
-				std::string badneighbors=".,<>/?';\"][}{=-+_)(*&^%$#@!~`";
-				m2 = badneighbors.find(line.substr(m1+1,1));
-				m3 = badneighbors.find(line.substr(m1-1,1));
-				if (m3<0 && m2<0)
-				{
-					matched = TRUE;
-				}
-			}
-		}
-	}
-	*/
-	
-	if (matched)
-	{
-		S32 strpos, strpos2;
-
-		std::string url     = line.substr(*begin,*end - *begin);
-		std::string slurlID = "slurl.com/secondlife/";
-		strpos = url.find(slurlID);
-		
-		if (strpos < 0)
-		{
-			slurlID="secondlife://";
-			strpos = url.find(slurlID);
-		}
-	
-		if (strpos < 0)
-		{
-			slurlID="sl://";
-			strpos = url.find(slurlID);
-		}
-	
-		if (strpos >= 0) 
-		{
-			strpos+=slurlID.length();
-			
-			while ( ( strpos2=url.find("/",strpos) ) == -1 ) 
-			{
-				if ((*end+2) >= (S32)line.length() || line.substr(*end,1) != " " )
-				{
-					matched=FALSE;
-					break;
-				}
-				
-				strpos = (*end + 1) - *begin;
-								
-				*end = findHTMLToken(line,(*begin + strpos),FALSE);
-				url = line.substr(*begin,*end - *begin);
-			}
-		}
-
-	}
-	
-	if (!matched)
-	{
-		*begin=*end=0;
-	}
-	return matched;
-}
-
-
-
 void LLTextEditor::updateAllowingLanguageInput()
 {
 	LLWindow* window = getWindow();
@@ -4753,193 +4580,6 @@ void	LLTextEditor::onValueChange(S32 start, S32 end)
 {
 }
 
-//
-// LLTextSegment
-//
-
-LLTextSegment::~LLTextSegment()
-{}
-
-S32	LLTextSegment::getWidth(S32 first_char, S32 num_chars) const { return 0; }
-S32	LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }
-S32	LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; }
-void LLTextSegment::updateLayout(const LLTextEditor& editor) {}
-F32	LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; }
-S32	LLTextSegment::getMaxHeight() const { return 0; }
-bool LLTextSegment::canEdit() const { return false; }
-void LLTextSegment::unlinkFromDocument(LLTextEditor*) {}
-void LLTextSegment::linkToDocument(LLTextEditor*) {}
-void LLTextSegment::setHasMouseHover(bool hover) {}
-const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; }
-void LLTextSegment::setColor(const LLColor4 &color) {}
-const LLStyleSP LLTextSegment::getStyle() const {static LLStyleSP sp(new LLStyle()); return sp; }
-void LLTextSegment::setStyle(const LLStyleSP &style) {}
-void LLTextSegment::setToken( LLKeywordToken* token ) {}
-LLKeywordToken*	LLTextSegment::getToken() const { return NULL; }
-BOOL LLTextSegment::getToolTip( std::string& msg ) const { return FALSE; }
-void LLTextSegment::dump() const {}
-
-
-//
-// LLNormalTextSegment
-//
-
-LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor ) 
-:	LLTextSegment(start, end),
-	mStyle( style ),
-	mToken(NULL),
-	mHasMouseHover(false),
-	mEditor(editor)
-{
-	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
-}
-
-LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible) 
-:	LLTextSegment(start, end),
-	mToken(NULL),
-	mHasMouseHover(false),
-	mEditor(editor)
-{
-	mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
-
-	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
-}
-
-F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
-{
-	if( end - start > 0 )
-	{
-		if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
-		{
-			S32 style_image_height = mStyle->mImageHeight;
-			S32 style_image_width = mStyle->mImageWidth;
-			LLUIImagePtr image = mStyle->getImage();
-			image->draw(draw_rect.mLeft, draw_rect.mTop-style_image_height, 
-				style_image_width, style_image_height);
-		}
-
-		return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect.mLeft, draw_rect.mBottom);
-	}
-	return draw_rect.mLeft;
-}
-
-// Draws a single text segment, reversing the color for selection if needed.
-F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y)
-{
-	const LLWString &text = mEditor.getWText();
-
-	F32 right_x = x;
-	if (!mStyle->isVisible())
-	{
-		return right_x;
-	}
-
-	const LLFontGL* font = mStyle->getFont();
-
-	LLColor4 color = mStyle->getColor();
-
-	font = mStyle->getFont();
-
-  	if( selection_start > seg_start )
-	{
-		// Draw normally
-		S32 start = seg_start;
-		S32 end = llmin( selection_start, seg_end );
-		S32 length =  end - start;
-		font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
-	}
-	x = right_x;
-	
-	if( (selection_start < seg_end) && (selection_end > seg_start) )
-	{
-		// Draw reversed
-		S32 start = llmax( selection_start, seg_start );
-		S32 end = llmin( selection_end, seg_end );
-		S32 length = end - start;
-
-		font->render(text, start, x, y,
-					 LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
-					 LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
-	}
-	x = right_x;
-	if( selection_end < seg_end )
-	{
-		// Draw normally
-		S32 start = llmax( selection_end, seg_start );
-		S32 end = seg_end;
-		S32 length = end - start;
-		font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
-	}
-	return right_x;
-}
-
-S32	LLNormalTextSegment::getMaxHeight() const	
-{ 
-	return mMaxHeight; 
-}
-
-BOOL LLNormalTextSegment::getToolTip(std::string& msg) const
-{
-	if (mToken && !mToken->getToolTip().empty())
-	{
-		const LLWString& wmsg = mToken->getToolTip();
-		msg = wstring_to_utf8str(wmsg);
-		return TRUE;
-	}
-	return FALSE;
-}
-
-
-S32	LLNormalTextSegment::getWidth(S32 first_char, S32 num_chars) const
-{
-	LLWString text = mEditor.getWText();
-	return mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
-}
-
-S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
-{
-	LLWString text = mEditor.getWText();
-	return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
-											   (F32)segment_local_x_coord,
-											   F32_MAX,
-											   num_chars,
-											   round);
-}
-
-S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
-{
-	LLWString text = mEditor.getWText();
-	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart, 
-												(F32)num_pixels,
-												max_chars, 
-												mEditor.getWordWrap());
-
-	if (num_chars == 0 
-		&& line_offset == 0 
-		&& max_chars > 0)
-	{
-		// If at the beginning of a line, and a single character won't fit, draw it anyway
-		num_chars = 1;
-	}
-	if (mStart + segment_offset + num_chars == mEditor.getLength())
-	{
-		// include terminating NULL
-		num_chars++;
-	}
-	return num_chars;
-}
-
-void LLNormalTextSegment::dump() const
-{
-	llinfos << "Segment [" << 
-//			mColor.mV[VX] << ", " <<
-//			mColor.mV[VY] << ", " <<
-//			mColor.mV[VZ] << "]\t[" <<
-		mStart << ", " <<
-		getEnd() << "]" <<
-		llendl;
-}
-
 //
 // LLInlineViewSegment
 //
@@ -4979,11 +4619,15 @@ S32	LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	}
 }
 
-void LLInlineViewSegment::updateLayout(const LLTextEditor& editor)
+void LLInlineViewSegment::updateLayout(const LLTextBase& editor)
 {
-	LLRect start_rect = editor.getLocalRectFromDocIndex(mStart);
-	LLRect doc_rect = editor.getDocumentPanel()->getRect();
-	mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom);
+	const LLTextEditor *ed = dynamic_cast<const LLTextEditor *>(&editor);
+	if (ed)
+	{
+		LLRect start_rect = ed->getLocalRectFromDocIndex(mStart);
+		LLRect doc_rect = ed->getDocumentPanel()->getRect();
+		mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom);
+	}
 }
 
 F32	LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
@@ -4996,12 +4640,20 @@ S32	LLInlineViewSegment::getMaxHeight() const
 	return mView->getRect().getHeight();
 }
 
-void LLInlineViewSegment::unlinkFromDocument(LLTextEditor* editor)
+void LLInlineViewSegment::unlinkFromDocument(LLTextBase* editor)
 {
-	editor->removeDocumentChild(mView);
+	LLTextEditor *ed = dynamic_cast<LLTextEditor *>(editor);
+	if (ed)
+	{
+		ed->removeDocumentChild(mView);
+	}
 }
 
-void LLInlineViewSegment::linkToDocument(LLTextEditor* editor)
+void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
 {
-	editor->addDocumentChild(mView);
+	LLTextEditor *ed = dynamic_cast<LLTextEditor *>(editor);
+	if (ed)
+	{
+		ed->addDocumentChild(mView);
+	}
 }
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 67c67d0f676de2813968ace41439d19929c72771..d5377511308be488dcb75076ed31bf0ddf6498aa 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -44,6 +44,7 @@
 #include "lleditmenuhandler.h"
 #include "lldarray.h"
 #include "llviewborder.h" // for params
+#include "lltextbase.h"
 
 #include "llpreeditor.h"
 #include "llcontrol.h"
@@ -55,76 +56,6 @@ class LLTextCmd;
 class LLUICtrlFactory;
 class LLScrollContainer;
 
-class LLTextSegment : public LLRefCount
-{
-public:
-	LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
-	virtual ~LLTextSegment();
-
-	virtual S32					getWidth(S32 first_char, S32 num_chars) const;
-	virtual S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
-	virtual S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
-	virtual void				updateLayout(const class LLTextEditor& editor);
-	virtual F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
-	virtual S32					getMaxHeight() const;
-	virtual bool				canEdit() const;
-	virtual void				unlinkFromDocument(class LLTextEditor* editor);
-	virtual void				linkToDocument(class LLTextEditor* editor);
-
-	virtual void				setHasMouseHover(bool hover);
-	virtual const LLColor4&		getColor() const;
-	virtual void 				setColor(const LLColor4 &color);
-	virtual const LLStyleSP		getStyle() const;
-	virtual void 				setStyle(const LLStyleSP &style);
-	virtual void				setToken( LLKeywordToken* token );
-	virtual LLKeywordToken*		getToken() const;
-	virtual BOOL				getToolTip( std::string& msg ) const;
-	virtual void				dump() const;
-
-	S32							getStart() const 					{ return mStart; }
-	void						setStart(S32 start)					{ mStart = start; }
-	S32							getEnd() const						{ return mEnd; }
-	void						setEnd( S32 end )					{ mEnd = end; }
-
-protected:
-	S32				mStart;
-	S32				mEnd;
-};
-
-class LLNormalTextSegment : public LLTextSegment
-{
-public:
-	LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor );
-	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible = TRUE);
-
-	/*virtual*/ S32					getWidth(S32 first_char, S32 num_chars) const;
-	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
-	/*virtual*/ S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
-	/*virtual*/ F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
-	/*virtual*/ S32					getMaxHeight() const;
-	/*virtual*/ bool				canEdit() const { return true; }
-	/*virtual*/ void				setHasMouseHover(bool hover)		{ mHasMouseHover = hover; }
-	/*virtual*/ const LLColor4&		getColor() const					{ return mStyle->getColor(); }
-	/*virtual*/ void 				setColor(const LLColor4 &color)		{ mStyle->setColor(color); }
-	/*virtual*/ const LLStyleSP		getStyle() const					{ return mStyle; }
-	/*virtual*/ void 				setStyle(const LLStyleSP &style)	{ mStyle = style; }
-	/*virtual*/ void				setToken( LLKeywordToken* token )	{ mToken = token; }
-	/*virtual*/ LLKeywordToken*		getToken() const					{ return mToken; }
-	/*virtual*/ BOOL				getToolTip( std::string& msg ) const;
-	/*virtual*/ void				dump() const;
-
-protected:
-	F32				drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y);
-
-	class LLTextEditor&	mEditor;
-	LLStyleSP		mStyle;
-	S32				mMaxHeight;
-	LLKeywordToken* mToken;
-	bool			mHasMouseHover;
-};
-
-typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
-
 class LLInlineViewSegment : public LLTextSegment
 {
 public:
@@ -132,24 +63,22 @@ class LLInlineViewSegment : public LLTextSegment
 	~LLInlineViewSegment();
 	/*virtual*/ S32			getWidth(S32 first_char, S32 num_chars) const;
 	/*virtual*/ S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
-	/*virtual*/ void		updateLayout(const class LLTextEditor& editor);
+	/*virtual*/ void		updateLayout(const class LLTextBase& editor);
 	/*virtual*/ F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
 	/*virtuaL*/ S32			getMaxHeight() const;
 	/*virtual*/ bool		canEdit() const { return false; }
-	/*virtual*/ void		unlinkFromDocument(class LLTextEditor* editor);
-	/*virtual*/ void		linkToDocument(class LLTextEditor* editor);
+	/*virtual*/ void		unlinkFromDocument(class LLTextBase* editor);
+	/*virtual*/ void		linkToDocument(class LLTextBase* editor);
 
 private:
 	LLView* mView;
 };
 
-class LLIndexSegment : public LLTextSegment
-{
-public:
-	LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
-};
-
-class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
+class LLTextEditor :
+	public LLTextBase,
+	public LLUICtrl,
+	private LLEditMenuHandler,
+	protected LLPreeditor
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
@@ -208,11 +137,8 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 		}
 	};
 
-	typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
-
 	virtual ~LLTextEditor();
 
-	void	setParseHTML(BOOL parsing) {mParseHTML=parsing;}
 	void	setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
 
 	// mousehandler overrides
@@ -277,6 +203,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	BOOL			replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
 	void			replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive);
 	BOOL			hasSelection() const		{ return (mSelectionStart !=mSelectionEnd); }
+	void			replaceUrlLabel(const std::string &url, const std::string &label);
 	
 	// Undo/redo stack
 	void			blockUndo();
@@ -285,7 +212,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	virtual void	makePristine();
 	BOOL			isPristine() const;
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
-	BOOL			getWordWrap() { return mWordWrap; }
 	S32				getLength() const { return getWText().length(); }
 	void			setReadOnly(bool read_only) { mReadOnly = read_only; }
 	bool			getReadOnly() { return mReadOnly; }
@@ -352,13 +278,11 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	const LLUUID&	getSourceID() const						{ return mSourceID; }
 
 	// Callbacks
-	static void		setURLCallbacks(void (*callback1) (const std::string& url), 
-									bool (*callback2) (const std::string& url),      
-									bool (*callback3) (const std::string& url)	) 
-									{ sURLcallback = callback1; sSecondlifeURLcallback = callback2; sSecondlifeURLcallbackRightClick = callback3;}
-
  	std::string     getText() const;
 	
+	// Callback for when a Url has been resolved by the server
+	void            onUrlLabelUpdated(const std::string &url, const std::string &label);
+
 	// Getters
 	LLWString       getWText() const;
 	llwchar			getWChar(S32 pos) const { return getWText()[pos]; }
@@ -382,8 +306,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	void			startOfDoc();
 	void			endOfDoc();
 
-	void			getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
-	void			getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ) ;
 	void			drawPreeditMarker();
 
 	void			needsReflow() { mReflowNeeded = TRUE; }
@@ -399,16 +321,12 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	
 	void			removeCharOrTab();
 	void			setCursorAtLocalPos(S32 x, S32 y, bool round, bool keep_cursor_offset = false);
-	S32				getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
+	/*virtual*/ S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
 
 	void			indentSelectedLines( S32 spaces );
 	S32				indentLine( S32 pos, S32 spaces );
 	void			unindentLineBeforeCloseBrace();
 
-	LLTextSegmentPtr				getSegmentAtLocalPos(S32 x, S32 y);
-	segment_set_t::iterator			getSegIterContaining(S32 index);
-	segment_set_t::const_iterator	getSegIterContaining(S32 index) const;
-
 	void			reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); }
 
 	BOOL			handleNavigationKey(const KEY key, const MASK mask);
@@ -438,15 +356,9 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	
 	void			findEmbeddedItemSegments(S32 start, S32 end);
 	void			insertSegment(LLTextSegmentPtr segment_to_insert);
-
 	
-	virtual BOOL	handleMouseUpOverSegment(S32 x, S32 y, MASK mask);
-
 	virtual llwchar	pasteEmbeddedItem(llwchar ext_char) { return ext_char; }
 	
-	S32				findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const;
-	BOOL			findHTML(const std::string &line, S32 *begin, S32 *end) const;
-
 	// Abstract inner base class representing an undoable editor command.
 	// Concrete sub-classes can be defined for operations such as insert, remove, etc.
 	// Used as arguments to the execute() method below.
@@ -538,13 +450,8 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	S32				mLastSelectionX;
 	S32				mLastSelectionY;
 
-	BOOL			mParseHTML;
 	BOOL			mParseHighlights;
-	std::string		mHTML;
 
-	segment_set_t mSegments;
-	LLTextSegmentPtr	mHoverSegment;
-	
 	// Scrollbar data
 	class DocumentPanel*	mDocumentPanel;
 	LLScrollContainer*	mScroller;
@@ -569,10 +476,10 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	LLUIColor		mLinkColor;
 
 	BOOL			mReadOnly;
-	BOOL			mWordWrap;
 	BOOL			mShowLineNumbers;
 
 	void			updateSegments();
+	void			updateLinkSegments();
 
 private:
 
@@ -584,7 +491,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	virtual 		LLTextViewModel* getViewModel() const;
 	void			reflow(S32 startpos = 0);
 
-	void			clearSegments();
 	void			createDefaultSegment();
 	LLStyleSP		getDefaultStyle();
 	S32				getEditableIndex(S32 index, bool increasing_direction);
@@ -601,9 +507,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	// Data
 	//
 	LLKeywords		mKeywords;
-	static void		(*sURLcallback) (const std::string& url);
-	static bool		(*sSecondlifeURLcallback) (const std::string& url);
-	static bool		(*sSecondlifeURLcallbackRightClick) (const std::string& url);
 
 	// Concrete LLTextCmd sub-classes used by the LLTextEditor base class
 	class LLTextCmdInsert;
@@ -613,8 +516,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 
 	S32				mMaxTextByteLength;		// Maximum length mText is allowed to be in bytes
 
-	const LLFontGL*	mDefaultFont;
-
 	class LLViewBorder*	mBorder;
 
 	BOOL			mBaseDocIsPristine;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 7ff942268dfb24a913c45e31cf22ffdc38c56b82..1ab04054ff76420a069c1997fd7ba21915765b30 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -257,6 +257,13 @@ BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask)
 	return handled;
 }
 
+BOOL LLUICtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = LLView::handleDoubleClick(x, y, mask);
+	mDoubleClickSignal(this, x, y, mask);
+	return handled;
+}
+
 // can't tab to children of a non-tab-stop widget
 BOOL LLUICtrl::canFocusChildren() const
 {
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3e2e1f41a1f278bcd10c835e448b6839004590ed..5011adcfe9800b7aeef1ad0d40b513253b2d249b 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -166,6 +166,7 @@ class LLUICtrl
 	/*virtual*/ BOOL 	handleMouseUp(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	// From LLFocusableElement
 	/*virtual*/ void	setFocus( BOOL b );
@@ -239,6 +240,8 @@ class LLUICtrl
 	boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); }
 	boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); }
 	
+	boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { return mDoubleClickSignal.connect(cb); }
+
 	// *TODO: Deprecate; for backwards compatability only:
 	boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data);	
 	boost::signals2::connection setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb );
@@ -273,6 +276,8 @@ class LLUICtrl
 	mouse_signal_t		mMouseUpSignal;
 	mouse_signal_t		mRightMouseDownSignal;
 	mouse_signal_t		mRightMouseUpSignal;
+
+	mouse_signal_t		mDoubleClickSignal;
 	
     LLViewModelPtr  mViewModel;
 
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b689b93c0af66d39ea6a2a5eac8e8d5dd8f7170
--- /dev/null
+++ b/indra/llui/llurlaction.cpp
@@ -0,0 +1,137 @@
+/** 
+ * @file llurlaction.cpp
+ * @author Martin Reddy
+ * @brief A set of actions that can performed on Urls
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llurlaction.h"
+#include "llview.h"
+#include "llwindow.h"
+#include "llurlregistry.h"
+
+// global state for the callback functions
+void (*LLUrlAction::sOpenURLCallback) (const std::string& url) = NULL;
+void (*LLUrlAction::sOpenURLInternalCallback) (const std::string& url) = NULL;
+void (*LLUrlAction::sOpenURLExternalCallback) (const std::string& url) = NULL;
+bool (*LLUrlAction::sExecuteSLURLCallback) (const std::string& url) = NULL;
+
+
+void LLUrlAction::setOpenURLCallback(void (*cb) (const std::string& url))
+{
+	sOpenURLCallback = cb;
+}
+
+void LLUrlAction::setOpenURLInternalCallback(void (*cb) (const std::string& url))
+{
+	sOpenURLInternalCallback = cb;
+}
+
+void LLUrlAction::setOpenURLExternalCallback(void (*cb) (const std::string& url))
+{
+	sOpenURLExternalCallback = cb;
+}
+
+void LLUrlAction::setExecuteSLURLCallback(bool (*cb) (const std::string& url))
+{
+	sExecuteSLURLCallback = cb;
+}
+
+void LLUrlAction::openURL(std::string url)
+{
+	if (sOpenURLCallback)
+	{
+		(*sOpenURLCallback)(url);
+	}
+}
+
+void LLUrlAction::openURLInternal(std::string url)
+{
+	if (sOpenURLInternalCallback)
+	{
+		(*sOpenURLInternalCallback)(url);
+	}
+}
+
+void LLUrlAction::openURLExternal(std::string url)
+{
+	if (sOpenURLExternalCallback)
+	{
+		(*sOpenURLExternalCallback)(url);
+	}
+}
+
+void LLUrlAction::executeSLURL(std::string url)
+{
+	if (sExecuteSLURLCallback)
+	{
+		(*sExecuteSLURLCallback)(url);
+	}
+}
+
+void LLUrlAction::clickAction(std::string url)
+{
+	// Try to handle as SLURL first, then http Url
+	if ( (sExecuteSLURLCallback) && !(*sExecuteSLURLCallback)(url) )
+	{
+		if (sOpenURLCallback)
+		{
+			(*sOpenURLCallback)(url);
+		}
+	}
+}
+
+void LLUrlAction::teleportToLocation(std::string url)
+{
+	LLUrlMatch match;
+	if (LLUrlRegistry::instance().findUrl(url, match))
+	{
+		if (! match.getLocation().empty())
+		{
+			executeSLURL("secondlife:///app/teleport/" + match.getLocation());
+		}
+	}	
+}
+
+void LLUrlAction::copyURLToClipboard(std::string url)
+{
+	LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url));
+}
+
+void LLUrlAction::copyLabelToClipboard(std::string url)
+{
+	LLUrlMatch match;
+	if (LLUrlRegistry::instance().findUrl(url, match))
+	{
+		LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
+	}	
+}
+
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b9d565b44ca97e9aebd599576375fe9c77224a1
--- /dev/null
+++ b/indra/llui/llurlaction.h
@@ -0,0 +1,93 @@
+/** 
+ * @file llurlaction.h
+ * @author Martin Reddy
+ * @brief A set of actions that can performed on Urls
+ *
+ * $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_LLURLACTION_H
+#define LL_LLURLACTION_H
+
+#include <string>
+
+///
+/// The LLUrlAction class provides a number of static functions that
+/// let you open Urls in web browsers, execute SLURLs, and copy Urls
+/// to the clipboard. Many of these functions are not available at
+/// the llui level, and must be supplied via a set of callbacks.
+///
+/// N.B. The action functions specifically do not use const ref
+/// strings so that a url parameter can be used into a boost::bind()
+/// call under situations when that input string is deallocated before
+/// the callback is executed.
+///
+class LLUrlAction
+{
+public:
+	LLUrlAction();
+
+	/// load a Url in the user's preferred web browser
+	static void openURL(std::string url);
+
+	/// load a Url in the internal Second Life web browser
+	static void openURLInternal(std::string url);
+
+	/// load a Url in the operating system's default web browser
+	static void openURLExternal(std::string url);
+
+	/// execute the given secondlife: SLURL
+	static void executeSLURL(std::string url);
+
+	/// if the Url specifies an SL location, teleport there
+	static void teleportToLocation(std::string url);
+
+	/// perform the appropriate action for left-clicking on a Url
+	static void clickAction(std::string url);
+
+	/// copy the label for a Url to the clipboard
+	static void copyLabelToClipboard(std::string url);
+
+	/// copy a Url to the clipboard
+	static void copyURLToClipboard(std::string url);
+
+	/// specify the callbacks to enable this class's functionality
+	static void	setOpenURLCallback(void (*cb) (const std::string& url));
+	static void	setOpenURLInternalCallback(void (*cb) (const std::string& url));
+	static void	setOpenURLExternalCallback(void (*cb) (const std::string& url));
+	static void	setExecuteSLURLCallback(bool (*cb) (const std::string& url));
+
+private:
+	// callbacks for operations we can perform on Urls
+	static void (*sOpenURLCallback) (const std::string& url);
+	static void (*sOpenURLInternalCallback) (const std::string& url);
+	static void (*sOpenURLExternalCallback) (const std::string& url);
+	static bool (*sExecuteSLURLCallback) (const std::string& url);
+};
+
+#endif
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..85f9064115146cdfcb17ac4b0e1e386ccf2f376a
--- /dev/null
+++ b/indra/llui/llurlentry.cpp
@@ -0,0 +1,546 @@
+/** 
+ * @file llurlentry.cpp
+ * @author Martin Reddy
+ * @brief Describes the Url types that can be registered in LLUrlRegistry
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llurlentry.h"
+#include "lluri.h"
+#include "llcachename.h"
+#include "lltrans.h"
+
+LLUrlEntryBase::LLUrlEntryBase()
+{
+}
+
+LLUrlEntryBase::~LLUrlEntryBase()
+{
+}
+
+std::string LLUrlEntryBase::getUrl(const std::string &string)
+{
+	return escapeUrl(string);
+}
+
+std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const
+{
+	// return the id from a SLURL in the format /app/{cmd}/{id}/about
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	if (path_array.size() == 4) 
+	{
+		return path_array.get(2).asString();
+	}
+	return "";
+}
+
+std::string LLUrlEntryBase::unescapeUrl(const std::string &url) const
+{
+	return LLURI::unescape(url);
+}
+
+std::string LLUrlEntryBase::escapeUrl(const std::string &url) const
+{
+	static std::string no_escape_chars;
+	static bool initialized = false;
+	if (!initialized)
+	{
+		no_escape_chars = 
+			"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+			"abcdefghijklmnopqrstuvwxyz"
+			"0123456789"
+			"-._~!$?&()*+,@:;=/%";
+
+		std::sort(no_escape_chars.begin(), no_escape_chars.end());
+		initialized = true;
+	}
+	return LLURI::escape(url, no_escape_chars, true);
+}
+
+std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url)
+{
+	// return the label part from [http://www.example.org Label]
+	const char *text = url.c_str();
+	S32 start = 0;
+	while (! isspace(text[start]))
+	{
+		start++;
+	}
+	while (text[start] == ' ' || text[start] == '\t')
+	{
+		start++;
+	}
+	return url.substr(start, url.size()-start-1);
+}
+
+std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string)
+{
+	// return the url part from [http://www.example.org Label]
+	const char *text = string.c_str();
+	S32 end = 0;
+	while (! isspace(text[end]))
+	{
+		end++;
+	}
+	return escapeUrl(string.substr(1, end-1));
+}
+
+void LLUrlEntryBase::addObserver(const std::string &id,
+								 const std::string &url,
+								 const LLUrlLabelCallback &cb)
+{
+	// add a callback to be notified when we have a label for the uuid
+	LLUrlEntryObserver observer;
+	observer.url = url;
+	observer.signal = new LLUrlLabelSignal();
+	if (observer.signal)
+	{
+		observer.signal->connect(cb);
+		mObservers.insert(std::pair<std::string, LLUrlEntryObserver>(id, observer));
+	}
+}
+ 
+void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label)
+{
+	// notify all callbacks waiting on the given uuid
+	std::multimap<std::string, LLUrlEntryObserver>::iterator it;
+	for (it = mObservers.find(id); it != mObservers.end();)
+	{
+		// call the callback - give it the new label
+		LLUrlEntryObserver &observer = it->second;
+		(*observer.signal)(it->second.url, label);
+		// then remove the signal - we only need to call it once
+		delete observer.signal;
+		mObservers.erase(it++);
+	}
+}
+
+//
+// LLUrlEntryHTTP Describes generic http: and https: Urls
+//
+LLUrlEntryHTTP::LLUrlEntryHTTP()
+{
+	mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_http.xml";
+	mTooltip = LLTrans::getString("TooltipHttpUrl");
+	//mIcon = "gear.tga";
+}
+
+std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return unescapeUrl(url);
+}
+
+//
+// LLUrlEntryHTTP Describes generic http: and https: Urls with custom label
+// We use the wikipedia syntax of [http://www.example.org Text]
+//
+LLUrlEntryHTTPLabel::LLUrlEntryHTTPLabel()
+{
+	mPattern = boost::regex("\\[https?://\\S+[ \t]+[^\\]]+\\]",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_http.xml";
+	mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+
+std::string LLUrlEntryHTTPLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return getLabelFromWikiLink(url);
+}
+
+std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string)
+{
+	return getUrlFromWikiLink(string);
+}
+
+//
+// LLUrlEntrySLURL Describes generic http: and https: Urls
+//
+LLUrlEntrySLURL::LLUrlEntrySLURL()
+{
+	// see http://slurl.com/about.php for details on the SLURL format
+	mPattern = boost::regex("http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_slurl.xml";
+	mTooltip = LLTrans::getString("TooltipSLURL");
+}
+
+std::string LLUrlEntrySLURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	//
+	// we handle SLURLs in the following formats:
+	//   - http://slurl.com/secondlife/Place/X/Y/Z
+	//   - http://slurl.com/secondlife/Place/X/Y
+	//   - http://slurl.com/secondlife/Place/X
+	//   - http://slurl.com/secondlife/Place
+	//
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	S32 path_parts = path_array.size();
+	if (path_parts == 5)
+	{
+		// handle slurl with (X,Y,Z) coordinates
+		std::string location = unescapeUrl(path_array[path_parts-4]);
+		std::string x = path_array[path_parts-3];
+		std::string y = path_array[path_parts-2];
+		std::string z = path_array[path_parts-1];
+		return location + " (" + x + "," + y + "," + z + ")";
+	}
+	else if (path_parts == 4)
+	{
+		// handle slurl with (X,Y) coordinates
+		std::string location = unescapeUrl(path_array[path_parts-3]);
+		std::string x = path_array[path_parts-2];
+		std::string y = path_array[path_parts-1];
+		return location + " (" + x + "," + y + ")";
+	}
+	else if (path_parts == 3)
+	{
+		// handle slurl with (X) coordinate
+		std::string location = unescapeUrl(path_array[path_parts-2]);
+		std::string x = path_array[path_parts-1];
+		return location + " (" + x + ")";
+	}
+	else if (path_parts == 2)
+	{
+		// handle slurl with no coordinates
+		std::string location = unescapeUrl(path_array[path_parts-1]);
+		return location;
+	}
+
+	return url;
+}
+
+std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
+{
+	// return the part of the Url after slurl.com/secondlife/
+	const std::string search_string = "secondlife";
+	size_t pos = url.find(search_string);
+	if (pos == std::string::npos)
+	{
+		return "";
+	}
+
+	pos += search_string.size() + 1;
+	return url.substr(pos, url.size() - pos);
+}
+
+//
+// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
+// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+//
+LLUrlEntryAgent::LLUrlEntryAgent()
+{
+	mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/about",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_agent.xml";
+	mTooltip = LLTrans::getString("TooltipAgentUrl");
+}
+
+void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id,
+										  const std::string& first,
+										  const std::string& last,
+										  BOOL is_group)
+{
+	// received the agent name from the server - tell our observers
+	callObservers(id.asString(), first + " " + last);
+}
+
+std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	std::string id = getIDStringFromUrl(url);
+	if (gCacheName && ! id.empty())
+	{
+		LLUUID uuid(id);
+		std::string full_name;
+		if (gCacheName->getFullName(uuid, full_name))
+		{
+			return full_name;
+		}
+		else
+		{
+			gCacheName->get(uuid, FALSE, boost::bind(&LLUrlEntryAgent::onAgentNameReceived, this, _1, _2, _3, _4));
+			addObserver(id, url, cb);
+		}
+	}
+
+	return unescapeUrl(url);
+}
+
+//
+// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
+// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
+//
+LLUrlEntryGroup::LLUrlEntryGroup()
+{
+	mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_group.xml";
+	mTooltip = LLTrans::getString("TooltipGroupUrl");
+}
+
+void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id,
+										  const std::string& first,
+										  const std::string& last,
+										  BOOL is_group)
+{
+	// received the group name from the server - tell our observers
+	callObservers(id.asString(), first);
+}
+
+std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	std::string id = getIDStringFromUrl(url);
+	if (gCacheName && ! id.empty())
+	{
+		LLUUID uuid(id);
+		std::string group_name;
+		if (gCacheName->getGroupName(uuid, group_name))
+		{
+			return group_name;
+		}
+		else
+		{
+			gCacheName->get(uuid, TRUE, boost::bind(&LLUrlEntryGroup::onGroupNameReceived, this, _1, _2, _3, _4));
+			addObserver(id, url, cb);
+		}
+	}
+
+	return unescapeUrl(url);
+}
+
+///
+/// LLUrlEntryEvent Describes a Second Life event Url, e.g.,
+/// secondlife:///app/event/700727/about
+///
+LLUrlEntryEvent::LLUrlEntryEvent()
+{
+	mPattern = boost::regex("secondlife:///app/event/[\\da-f-]+/about",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_event.xml";
+	mTooltip = LLTrans::getString("TooltipEventUrl");
+}
+
+std::string LLUrlEntryEvent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return unescapeUrl(url);
+}
+
+///
+/// LLUrlEntryClassified Describes a Second Life classified Url, e.g.,
+/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about
+///
+LLUrlEntryClassified::LLUrlEntryClassified()
+{
+	mPattern = boost::regex("secondlife:///app/classified/[\\da-f-]+/about",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_classified.xml";
+	mTooltip = LLTrans::getString("TooltipClassifiedUrl");
+}
+
+std::string LLUrlEntryClassified::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return unescapeUrl(url);
+}
+
+///
+/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
+/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+///
+LLUrlEntryParcel::LLUrlEntryParcel()
+{
+	mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_parcel.xml";
+	mTooltip = LLTrans::getString("TooltipParcelUrl");
+}
+
+std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return unescapeUrl(url);
+}
+
+//
+// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
+// secondlife:///app/teleport/Ahern/50/50/50/
+//
+LLUrlEntryTeleport::LLUrlEntryTeleport()
+{
+	mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_teleport.xml";
+	mTooltip = LLTrans::getString("TooltipTeleportUrl");
+}
+
+std::string LLUrlEntryTeleport::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	//
+	// we handle teleport SLURLs in the following formats:
+	//   - secondlife:///app/teleport/Place/X/Y/Z
+	//   - secondlife:///app/teleport/Place/X/Y
+	//   - secondlife:///app/teleport/Place/X
+	//   - secondlife:///app/teleport/Place
+	//
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	S32 path_parts = path_array.size();
+	if (path_parts == 6)
+	{
+		// handle teleport url with (X,Y,Z) coordinates
+		std::string location = unescapeUrl(path_array[path_parts-4]);
+		std::string x = path_array[path_parts-3];
+		std::string y = path_array[path_parts-2];
+		std::string z = path_array[path_parts-1];
+		return "Teleport to " + location + " (" + x + "," + y + "," + z + ")";
+	}
+	else if (path_parts == 5)
+	{
+		// handle teleport url with (X,Y) coordinates
+		std::string location = unescapeUrl(path_array[path_parts-3]);
+		std::string x = path_array[path_parts-2];
+		std::string y = path_array[path_parts-1];
+		return "Teleport to " + location + " (" + x + "," + y + ")";
+	}
+	else if (path_parts == 4)
+	{
+		// handle teleport url with (X) coordinate only
+		std::string location = unescapeUrl(path_array[path_parts-2]);
+		std::string x = path_array[path_parts-1];
+		return "Teleport to " + location + " (" + x + ")";
+	}
+	else if (path_parts == 3)
+	{
+		// handle teleport url with no coordinates
+		std::string location = unescapeUrl(path_array[path_parts-1]);
+		return "Teleport to " + location;
+	}
+
+	return url;
+}
+
+std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
+{
+	// return the part of the Url after ///app/teleport
+	const std::string search_string = "teleport";
+	size_t pos = url.find(search_string);
+	if (pos == std::string::npos)
+	{
+		return "";
+	}
+
+	pos += search_string.size() + 1;
+	return url.substr(pos, url.size() - pos);
+}
+
+///
+/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
+/// secondlife:///app/objectim/<sessionid>
+///
+LLUrlEntryObjectIM::LLUrlEntryObjectIM()
+{
+	mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_objectim.xml";
+	mTooltip = LLTrans::getString("TooltipObjectIMUrl");
+}
+
+std::string LLUrlEntryObjectIM::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	LLURI uri(url);
+	LLSD params = uri.queryMap();
+	if (params.has("name"))
+	{
+		// look for a ?name=<obj-name> param in the url
+		// and use that as the label if present.
+		std::string name = params.get("name");
+		LLStringUtil::trim(name);
+		if (name.empty())
+		{
+			name = LLTrans::getString("Unnamed");
+		}
+		return name;
+	}
+
+	return unescapeUrl(url);
+}
+
+std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
+{
+	LLURI uri(url);
+	LLSD params = uri.queryMap();
+	if (params.has("slurl"))
+	{
+		return params.get("slurl");
+	}
+
+	return "";
+}
+
+//
+// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
+// with secondlife:// (used as a catch-all for cases not matched above)
+//
+LLUrlEntrySL::LLUrlEntrySL()
+{
+	mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_slapp.xml";
+	mTooltip = LLTrans::getString("TooltipSLAPP");
+}
+
+std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return unescapeUrl(url);
+}
+
+//
+// LLUrlEntrySLLabel Describes a generic SLURL, e.g., a Url that starts
+/// with secondlife:// with the ability to specify a custom label.
+//
+LLUrlEntrySLLabel::LLUrlEntrySLLabel()
+{
+	mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_slapp.xml";
+	mTooltip = LLTrans::getString("TooltipSLAPP");
+}
+
+std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return getLabelFromWikiLink(url);
+}
+
+std::string LLUrlEntrySLLabel::getUrl(const std::string &string)
+{
+	return getUrlFromWikiLink(string);
+}
+
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3e76dbec00dfe4b96ad75068d94c4b734a5db8e
--- /dev/null
+++ b/indra/llui/llurlentry.h
@@ -0,0 +1,252 @@
+/** 
+ * @file llurlentry.h
+ * @author Martin Reddy
+ * @brief Describes the Url types that can be registered in LLUrlRegistry
+ *
+ * $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_LLURLENTRY_H
+#define LL_LLURLENTRY_H
+
+#include "lluuid.h"
+
+#include <boost/signals2.hpp>
+#include <boost/regex.hpp>
+#include <string>
+#include <map>
+
+typedef boost::signals2::signal<void (const std::string& url,
+									  const std::string& label)> LLUrlLabelSignal;
+typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback;
+
+///
+/// LLUrlEntryBase is the base class of all Url types registered in the 
+/// LLUrlRegistry. Each derived classes provides a regular expression
+/// to match the Url type (e.g., http://... or secondlife://...) along
+/// with an optional icon to display next to instances of the Url in
+/// a text display and a XUI file to use for any context menu popup.
+/// Functions are also provided to compute an appropriate label and
+/// tooltip/status bar text for the Url.
+///
+/// Some derived classes of LLUrlEntryBase may wish to compute an
+/// appropriate label for a Url by asking the server for information.
+/// You must therefore provide a callback method, so that you can be
+/// notified when an updated label has been received from the server.
+/// This label should then be used to replace any previous label
+/// that you received from getLabel() for the Url in question.
+///
+class LLUrlEntryBase
+{
+public:
+	LLUrlEntryBase();
+	virtual ~LLUrlEntryBase();
+	
+	/// Return the regex pattern that matches this Url 
+	boost::regex getPattern() const { return mPattern; }
+
+	/// Return the url from a string that matched the regex
+	virtual std::string getUrl(const std::string &string);
+
+	/// Given a matched Url, return a label for the Url
+	virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
+
+	/// Return an icon that can be displayed next to Urls of this type
+	const std::string &getIcon() const { return mIcon; }
+
+	/// Given a matched Url, return a tooltip string for the hyperlink
+	std::string getTooltip() const { return mTooltip; }
+
+	/// Return the name of a XUI file containing the context menu items
+	const std::string getMenuName() const { return mMenuName; }
+
+	/// Return the name of a SL location described by this Url, if any
+	virtual std::string getLocation(const std::string &url) const { return ""; }
+
+protected:
+	std::string getIDStringFromUrl(const std::string &url) const;
+	std::string escapeUrl(const std::string &url) const;
+	std::string unescapeUrl(const std::string &url) const;
+	std::string getLabelFromWikiLink(const std::string &url);
+	std::string getUrlFromWikiLink(const std::string &string);
+	void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb); 
+	void callObservers(const std::string &id, const std::string &label);
+
+	typedef struct {
+		std::string url;
+		LLUrlLabelSignal *signal;
+	} LLUrlEntryObserver;
+
+	boost::regex                                   mPattern;
+	std::string                                    mIcon;
+	std::string                                    mMenuName;
+	std::string                                    mTooltip;
+	std::multimap<std::string, LLUrlEntryObserver> mObservers;
+};
+
+///
+/// LLUrlEntryHTTP Describes generic http: and https: Urls
+///
+class LLUrlEntryHTTP : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryHTTP();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
+///
+/// LLUrlEntryHTTPLabel Describes generic http: and https: Urls with custom labels
+///
+class LLUrlEntryHTTPLabel : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryHTTPLabel();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getUrl(const std::string &string);
+};
+
+///
+/// LLUrlEntrySLURL Describes http://slurl.com/... Urls
+///
+class LLUrlEntrySLURL : public LLUrlEntryBase
+{
+public:
+	LLUrlEntrySLURL();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getLocation(const std::string &url) const;
+};
+
+///
+/// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
+/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+///
+class LLUrlEntryAgent : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryAgent();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+private:
+	void onAgentNameReceived(const LLUUID& id, const std::string& first,
+							 const std::string& last, BOOL is_group);
+};
+
+///
+/// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
+/// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
+///
+class LLUrlEntryGroup : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryGroup();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+private:
+	void onGroupNameReceived(const LLUUID& id, const std::string& first,
+							 const std::string& last, BOOL is_group);
+};
+
+///
+/// LLUrlEntryEvent Describes a Second Life event Url, e.g.,
+/// secondlife:///app/event/700727/about
+///
+class LLUrlEntryEvent : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryEvent();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
+///
+/// LLUrlEntryClassified Describes a Second Life classified Url, e.g.,
+/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about
+///
+class LLUrlEntryClassified : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryClassified();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
+///
+/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
+/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+///
+class LLUrlEntryParcel : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryParcel();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
+///
+/// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
+/// secondlife:///app/teleport/Ahern/50/50/50/
+///
+class LLUrlEntryTeleport : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryTeleport();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getLocation(const std::string &url) const;
+};
+
+///
+/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
+/// secondlife:///app/objectim/<sessionid>?name=Foo
+///
+class LLUrlEntryObjectIM : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryObjectIM();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getLocation(const std::string &url) const;
+};
+
+///
+/// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
+/// with secondlife:// (used as a catch-all for cases not matched above)
+///
+class LLUrlEntrySL : public LLUrlEntryBase
+{
+public:
+	LLUrlEntrySL();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
+///
+/// LLUrlEntrySLLabel Describes a generic SLURL, e.g., a Url that starts
+/// with secondlife:// with the ability to specify a custom label.
+///
+class LLUrlEntrySLLabel : public LLUrlEntryBase
+{
+public:
+	LLUrlEntrySLLabel();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getUrl(const std::string &string);
+};
+
+#endif
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7eec4c4a659c62fd02ff3cb074345f34e9ef3689
--- /dev/null
+++ b/indra/llui/llurlmatch.cpp
@@ -0,0 +1,61 @@
+/** 
+ * @file llurlmatch.cpp
+ * @author Martin Reddy
+ * @brief Specifies a matched Url in a string, as returned by LLUrlRegistry
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llurlmatch.h"
+
+LLUrlMatch::LLUrlMatch() :
+	mStart(0),
+	mEnd(0),
+	mUrl(""),
+	mLabel(""),
+	mTooltip(""),
+	mIcon(""),
+	mMenuName("")
+{
+}
+
+void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
+						   const std::string &label, const std::string &tooltip,
+						   const std::string &icon, const std::string &menu,
+						   const std::string &location)
+{
+	mStart = start;
+	mEnd = end;
+	mUrl = url;
+	mLabel = label;
+	mTooltip = tooltip;
+	mIcon = icon;
+	mMenuName = menu;
+	mLocation = location;
+}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..0711e41443823774e5866fcb3bcc4a2f5b6382c3
--- /dev/null
+++ b/indra/llui/llurlmatch.h
@@ -0,0 +1,98 @@
+/** 
+ * @file llurlmatch.h
+ * @author Martin Reddy
+ * @brief Specifies a matched Url in a string, as returned by LLUrlRegistry
+ *
+ * $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_LLURLMATCH_H
+#define LL_LLURLMATCH_H
+
+#include "linden_common.h"
+
+#include <string>
+#include <vector>
+
+///
+/// LLUrlMatch describes a single Url that was matched within a string by 
+/// the LLUrlRegistry::findUrl() method. It includes the actual Url that
+/// was matched along with its first/last character offset in the string.
+/// An alternate label is also provided for creating a hyperlink, as well
+/// as tooltip/status text, an icon, and a XUI file for a context menu
+/// that can be used in a popup for a Url (e.g., Open, Copy URL, etc.)
+///
+class LLUrlMatch
+{
+public:
+	LLUrlMatch();
+
+	/// return true if this object does not contain a valid Url match yet
+	bool empty() const { return mUrl.empty(); }
+
+	/// return the offset in the string for the first character of the Url
+	U32 getStart() const { return mStart; }
+
+	/// return the offset in the string for the last character of the Url
+	U32 getEnd() const { return mEnd; }
+
+	/// return the Url that has been matched in the input string
+	const std::string &getUrl() const { return mUrl; }
+
+	/// return a label that can be used for the display of this Url
+	const std::string &getLabel() const { return mLabel; }
+
+	/// return a message that could be displayed in a tooltip or status bar
+	const std::string &getTooltip() const { return mTooltip; }
+
+	/// return the filename for an icon that can be displayed next to this Url
+	const std::string &getIcon() const { return mIcon; }
+
+	/// Return the name of a XUI file containing the context menu items
+	const std::string getMenuName() const { return mMenuName; }
+
+	/// return the SL location that this Url describes, or "" if none.
+	const std::string &getLocation() const { return mLocation; }
+
+	/// Change the contents of this match object (used by LLUrlRegistry)
+	void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
+	               const std::string &tooltip, const std::string &icon,
+				   const std::string &menu, const std::string &location);
+
+private:
+	U32         mStart;
+	U32         mEnd;
+	std::string mUrl;
+	std::string mLabel;
+	std::string mTooltip;
+	std::string mIcon;
+	std::string mMenuName;
+	std::string mLocation;
+};
+
+#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..938375ad13e514c91869954ca8b9804483871de3
--- /dev/null
+++ b/indra/llui/llurlregistry.cpp
@@ -0,0 +1,165 @@
+/** 
+ * @file llurlregistry.cpp
+ * @author Martin Reddy
+ * @brief Contains a set of Url types that can be matched in a string
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llurlregistry.h"
+
+#include <boost/regex.hpp>
+
+// default dummy callback that ignores any label updates from the server
+void LLUrlRegistryNullCallback(const std::string &url, const std::string &label)
+{
+}
+
+LLUrlRegistry::LLUrlRegistry()
+{
+	// Urls are matched in the order that they were registered
+	registerUrl(new LLUrlEntrySLURL());
+	registerUrl(new LLUrlEntryHTTP());
+	registerUrl(new LLUrlEntryHTTPLabel());
+	registerUrl(new LLUrlEntryAgent());
+	registerUrl(new LLUrlEntryGroup());
+	registerUrl(new LLUrlEntryEvent());
+	registerUrl(new LLUrlEntryClassified());
+	registerUrl(new LLUrlEntryParcel());
+	registerUrl(new LLUrlEntryTeleport());
+	registerUrl(new LLUrlEntryObjectIM());
+	registerUrl(new LLUrlEntrySL());
+	registerUrl(new LLUrlEntrySLLabel());
+}
+
+LLUrlRegistry::~LLUrlRegistry()
+{
+	// free all of the LLUrlEntryBase objects we are holding
+	std::vector<LLUrlEntryBase *>::iterator it;
+	for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
+	{
+		delete *it;
+	}
+}
+
+void LLUrlRegistry::registerUrl(LLUrlEntryBase *url)
+{
+	if (url)
+	{
+		mUrlEntry.push_back(url);
+	}
+}
+
+static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &end)
+{
+	boost::cmatch result;
+	bool found;
+
+	// regex_search can potentially throw an exception, so check for it
+	try
+	{
+		found = boost::regex_search(text, result, regex);
+	}
+	catch (std::runtime_error &)
+	{
+		return false;
+	}
+
+	if (! found)
+	{
+		return false;
+	}
+
+	// return the first/last character offset for the matched substring
+	start = static_cast<U32>(result[0].first - text);
+	end = static_cast<U32>(result[0].second - text) - 1;
+
+	// we allow certain punctuation to terminate a Url but not match it,
+	// e.g., "http://foo.com/." should just match "http://foo.com/"
+	if (text[end] == '.' || text[end] == ',')
+	{
+		end--;
+	}
+	// ignore a terminating ')' when Url contains no matching '('
+	// see DEV-19842 for details
+	else if (text[end] == ')' && std::string(text+start, end-start).find('(') == std::string::npos)
+	{
+		end--;
+	}
+
+	return true;
+}
+
+bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
+{
+	// test for the trivial case of no text and get out fast
+	if (text.empty())
+	{
+		return false;
+	}
+
+	// find the first matching regex from all url entries in the registry
+	U32 match_start = 0, match_end = 0;
+	LLUrlEntryBase *match_entry = NULL;
+
+	std::vector<LLUrlEntryBase *>::iterator it;
+	for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
+	{
+		LLUrlEntryBase *url_entry = *it;
+
+		U32 start = 0, end = 0;
+		if (matchRegex(text.c_str(), url_entry->getPattern(), start, end))
+		{
+			// does this match occur in the string before any other match
+			if (start < match_start || match_entry == NULL)
+			{
+				match_start = start;
+				match_end = end;
+				match_entry = url_entry;
+			}
+		}
+	}
+	
+	// did we find a match? if so, return its details in the match object
+	if (match_entry)
+	{
+		// fill in the LLUrlMatch object and return it
+		std::string url = text.substr(match_start, match_end - match_start + 1);
+		match.setValues(match_start, match_end,
+						match_entry->getUrl(url),
+						match_entry->getLabel(url, cb),
+						match_entry->getTooltip(),
+						match_entry->getIcon(),
+						match_entry->getMenuName(),
+						match_entry->getLocation(url));
+		return true;
+	}
+
+	return false;
+}
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
new file mode 100644
index 0000000000000000000000000000000000000000..84b033036c580b4c47d78f2bd2d72be2a3551e33
--- /dev/null
+++ b/indra/llui/llurlregistry.h
@@ -0,0 +1,87 @@
+/** 
+ * @file llurlregistry.h
+ * @author Martin Reddy
+ * @brief Contains a set of Url types that can be matched in a string
+ *
+ * $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_LLURLREGISTRY_H
+#define LL_LLURLREGISTRY_H
+
+#include "llurlentry.h"
+#include "llurlmatch.h"
+#include "llsingleton.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+/// This default callback for findUrl() simply ignores any label updates
+void LLUrlRegistryNullCallback(const std::string &url, const std::string &label);
+
+///
+/// LLUrlRegistry is a singleton that contains a set of Url types that
+/// can be matched in string. E.g., http:// or secondlife:// Urls.
+///
+/// Clients call the findUrl() method on a string to locate the first
+/// occurence of a supported Urls in that string. If findUrl() returns
+/// true, the LLUrlMatch object will be updated to describe the Url
+/// that was matched, including a label that can be used to hyperlink
+/// the Url, an icon to display next to the Url, and a XUI menu that
+/// can be used as a popup context menu for that Url.
+///
+/// New Url types can be added to the registry with the registerUrl
+/// method. E.g., to add support for a new secondlife:///app/ Url.
+///
+/// Computing the label for a Url could involve a roundtrip request
+/// to the server (e.g., to find the actual agent or group name).
+/// As such, you can provide a callback method that will get invoked
+/// when a new label is available for one of your matched Urls.
+///
+class LLUrlRegistry : public LLSingleton<LLUrlRegistry>
+{
+public:
+	~LLUrlRegistry();
+
+	/// add a new Url handler to the registry (will be freed on destruction)
+	void registerUrl(LLUrlEntryBase *url);
+
+	/// get the next Url in an input string, starting at a given character offset
+	/// your callback is invoked if the matched Url's label changes in the future
+	bool findUrl(const std::string &text, LLUrlMatch &match,
+				 const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback);
+
+private:
+	LLUrlRegistry();
+	friend class LLSingleton<LLUrlRegistry>;
+
+	std::vector<LLUrlEntryBase *> mUrlEntry;
+};
+
+#endif
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 4770807ac7fe7baa62c893a65171c486010e0643..55d94b325f1d950ba81e66ab2ac7215bde66af59 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -2735,3 +2735,17 @@ LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
 	}
 	return *mDefaultWidgets;
 }
+void	LLView::notifyParent(const LLSD& info)
+{
+	LLView* parent = getParent();
+	if(parent)
+		parent->notifyParent(info);
+}
+void	LLView::notifyChildren(const LLSD& info)
+{
+	for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
+	{
+		(*child_it)->notifyChildren(info);
+	}
+}
+
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index ecc6bf47da2aaf570a5c411e39140cf07a49b89f..1d48378081faf03fc97ec3b5960174e171221bcd 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -549,6 +549,9 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 
 	virtual void	handleReshape(const LLRect& rect, bool by_user);
 
+	virtual void	notifyParent(const LLSD& info);
+	virtual void	notifyChildren(const LLSD& info);
+
 protected:
 	void			drawDebugRect();
 	void			drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..26d1f2e0671bf205370e4f08f9fb2a3e46b7b5b0
--- /dev/null
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -0,0 +1,64 @@
+/**
+ * @file llurlentry_stub.cpp
+ * @author Martin Reddy
+ * @brief Stub implementations for LLUrlEntry unit test dependencies
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
+ * this source code is governed by the Linden Lab Source Code Disclosure
+ * Agreement ("Agreement") previously entered between you and Linden
+ * Lab. By accessing, using, copying, modifying or distributing this
+ * software, you acknowledge that you have been informed of your
+ * obligations under the Agreement 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 "llstring.h"
+#include "llfile.h"
+#include "llcachename.h"
+#include "lluuid.h"
+
+#include <string>
+
+//
+// Stub implementation for LLCacheName
+//
+BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
+{
+	fullname = "Lynx Linden";
+	return TRUE;
+}
+
+BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
+{
+	group = "My Group";
+	return TRUE;
+}
+
+boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback)
+{
+	return boost::signals2::connection();
+}
+
+LLCacheName* gCacheName = NULL;
+
+//
+// Stub implementation for LLTrans
+//
+class LLTrans
+{
+public:
+	static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+};
+
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args)
+{
+	return std::string();
+}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..610ee3349b0132e02d0eeab67a61ebadc854ca2c
--- /dev/null
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -0,0 +1,535 @@
+/**
+ * @file llurlentry_test.cpp
+ * @author Martin Reddy
+ * @brief Unit tests for LLUrlEntry objects
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
+ * this source code is governed by the Linden Lab Source Code Disclosure
+ * Agreement ("Agreement") previously entered between you and Linden
+ * Lab. By accessing, using, copying, modifying or distributing this
+ * software, you acknowledge that you have been informed of your
+ * obligations under the Agreement 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 "../llurlentry.h"
+#include "llurlentry_stub.cpp"
+#include "lltut.h"
+
+#include <boost/regex.hpp>
+
+namespace tut
+{
+	struct LLUrlEntryData
+	{
+	};
+
+	typedef test_group<LLUrlEntryData> factory;
+	typedef factory::object object;
+}
+
+namespace
+{
+	tut::factory tf("LLUrlEntry");
+}
+
+namespace tut
+{
+	void testRegex(const std::string &testname, boost::regex regex,
+				   const char *text, const std::string &expected)
+	{
+		std::string url = "";
+		boost::cmatch result;
+		bool found = boost::regex_search(text, result, regex);
+		if (found)
+		{
+			S32 start = static_cast<U32>(result[0].first - text);
+			S32 end = static_cast<U32>(result[0].second - text);
+			url = std::string(text+start, end-start);
+		}
+		ensure_equals(testname, url, expected);
+	}
+
+	template<> template<>
+	void object::test<1>()
+	{
+		//
+		// test LLUrlEntryHTTP - standard http Urls
+		//
+		LLUrlEntryHTTP url;
+		boost::regex r = url.getPattern();
+
+		testRegex("no valid url", r,
+				  "htp://slurl.com/",
+				  "");
+
+		testRegex("simple http (1)", r,
+				  "http://slurl.com/",
+				  "http://slurl.com/");
+
+		testRegex("simple http (2)", r,
+				  "http://slurl.com",
+				  "http://slurl.com");
+
+		testRegex("simple http (3)", r,
+				  "http://slurl.com/about.php",
+				  "http://slurl.com/about.php");
+
+		testRegex("simple https", r,
+				  "https://slurl.com/about.php",
+				  "https://slurl.com/about.php");
+
+		testRegex("http in text (1)", r,
+				  "XX http://slurl.com/ XX",
+				  "http://slurl.com/");
+
+		testRegex("http in text (2)", r,
+				  "XX http://slurl.com/about.php XX",
+				  "http://slurl.com/about.php");
+
+		testRegex("https in text", r,
+				  "XX https://slurl.com/about.php XX",
+				  "https://slurl.com/about.php");
+
+		testRegex("two http urls", r,
+				  "XX http://slurl.com/about.php http://secondlife.com/ XX",
+				  "http://slurl.com/about.php");
+
+		testRegex("http url with port and username", r,
+				  "XX http://nobody@slurl.com:80/about.php http://secondlife.com/ XX",
+				  "http://nobody@slurl.com:80/about.php");
+
+		testRegex("http url with port, username, and query string", r,
+				  "XX http://nobody@slurl.com:80/about.php?title=hi%20there http://secondlife.com/ XX",
+				  "http://nobody@slurl.com:80/about.php?title=hi%20there");
+
+		// note: terminating commas will be removed by LLUrlRegistry:findUrl()
+		testRegex("http url with commas in middle and terminating", r,
+				  "XX http://slurl.com/?title=Hi,There, XX",
+				  "http://slurl.com/?title=Hi,There,");
+
+		// note: terminating periods will be removed by LLUrlRegistry:findUrl()
+		testRegex("http url with periods in middle and terminating", r,
+				  "XX http://slurl.com/index.php. XX",
+				  "http://slurl.com/index.php.");
+
+		// DEV-19842: Closing parenthesis ")" breaks urls
+		testRegex("http url with brackets (1)", r,
+				  "XX http://en.wikipedia.org/wiki/JIRA_(software) XX",
+				  "http://en.wikipedia.org/wiki/JIRA_(software)");
+
+		// DEV-19842: Closing parenthesis ")" breaks urls
+		testRegex("http url with brackets (2)", r, 
+				  "XX http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg XX",
+				  "http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg");
+
+		// DEV-10353: URLs in chat log terminated incorrectly when newline in chat
+		testRegex("http url with newlines", r,
+				  "XX\nhttp://www.secondlife.com/\nXX",
+				  "http://www.secondlife.com/");
+	}
+
+	template<> template<>
+	void object::test<2>()
+	{
+		//
+		// test LLUrlEntryHTTPLabel - wiki-style http Urls with labels
+		//
+		LLUrlEntryHTTPLabel url;
+		boost::regex r = url.getPattern();
+
+		testRegex("invalid wiki url [1]", r,
+				  "[http://www.example.org]",
+				  "");
+
+		testRegex("invalid wiki url [2]", r,
+				  "[http://www.example.org",
+				  "");
+
+		testRegex("invalid wiki url [3]", r,
+				  "[http://www.example.org Label",
+				  "");
+
+		testRegex("example.org with label (spaces)", r,
+				  "[http://www.example.org  Text]",
+				  "[http://www.example.org  Text]");
+
+		testRegex("example.org with label (tabs)", r,
+				  "[http://www.example.org\t Text]",
+				  "[http://www.example.org\t Text]");
+
+		testRegex("SL http URL with label", r,
+				  "[http://www.secondlife.com/ Second Life]",
+				  "[http://www.secondlife.com/ Second Life]");
+
+		testRegex("SL https URL with label", r,
+				  "XXX [https://www.secondlife.com/ Second Life] YYY",
+				  "[https://www.secondlife.com/ Second Life]");
+
+		testRegex("SL http URL with label", r,
+				  "[http://www.secondlife.com/?test=Hi%20There Second Life]",
+				  "[http://www.secondlife.com/?test=Hi%20There Second Life]");
+	}
+
+	template<> template<>
+	void object::test<3>()
+	{
+		//
+		// test LLUrlEntrySLURL - second life URLs
+		//
+		LLUrlEntrySLURL url;
+		boost::regex r = url.getPattern();
+
+		testRegex("no valid slurl [1]", r,
+				  "htp://slurl.com/secondlife/Ahern/50/50/50/",
+				  "");
+
+		testRegex("no valid slurl [2]", r,
+				  "http://slurl.com/secondlife/",
+				  "");
+
+		testRegex("no valid slurl [3]", r,
+				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",
+				  "");
+
+		testRegex("Ahern (50,50,50) [1]", r,
+				  "http://slurl.com/secondlife/Ahern/50/50/50/",
+				  "http://slurl.com/secondlife/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [2]", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/ XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [3]", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50/50 XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50/50");
+
+		testRegex("Ahern (50,50,50) multicase", r,
+				  "XXX http://SLUrl.com/SecondLife/Ahern/50/50/50/ XXX",
+				  "http://SLUrl.com/SecondLife/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50) [1]", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50/ XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50/");
+
+		testRegex("Ahern (50,50) [2]", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50 XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50");
+
+		testRegex("Ahern (50)", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50 XXX",
+				  "http://slurl.com/secondlife/Ahern/50");
+
+		testRegex("Ahern", r,
+				  "XXX http://slurl.com/secondlife/Ahern/ XXX",
+				  "http://slurl.com/secondlife/Ahern/");
+
+		testRegex("Ahern SLURL with title", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!");
+
+		testRegex("Ahern SLURL with msg", r,
+				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here. XXX",
+				  "http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here.");
+
+		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
+		testRegex("SLURL with brackets", r,
+				  "XXX http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30 XXX",
+				  "http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30");
+
+		// DEV-35459: SLURLs and teleport Links not parsed properly
+		testRegex("SLURL with quote", r,
+				  "XXX http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701 XXX",
+				  "http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701");
+	}
+
+	template<> template<>
+	void object::test<4>()
+	{
+		//
+		// test LLUrlEntryAgent - secondlife://app/agent Urls
+		//
+		LLUrlEntryAgent url;
+		boost::regex r = url.getPattern();
+
+		testRegex("Invalid Agent Url", r,
+				  "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",
+				  "");
+
+		testRegex("Agent Url ", r,
+				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+
+		testRegex("Agent Url in text", r,
+				  "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX",
+				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+
+		testRegex("Agent Url multicase", r,
+				  "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",
+				  "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About");
+	}
+
+	template<> template<>
+	void object::test<5>()
+	{
+		//
+		// test LLUrlEntryGroup - secondlife://app/group Urls
+		//
+		LLUrlEntryGroup url;
+		boost::regex r = url.getPattern();
+
+		testRegex("Invalid Group Url", r,
+				  "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about",
+				  "");
+
+		testRegex("Group Url ", r,
+				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about",
+				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about");
+
+		testRegex("Group Url in text", r,
+				  "XXX secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about XXX",
+				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about");
+
+		testRegex("Group Url multicase", r,
+				  "XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX",
+				  "secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About");
+	}
+
+	template<> template<>
+	void object::test<6>()
+	{
+		//
+		// test LLUrlEntryEvent - secondlife://app/event Urls
+		//
+		LLUrlEntryEvent url;
+		boost::regex r = url.getPattern();
+
+		testRegex("Invalid Event Url", r,
+				  "secondlife:///app/event/FOO/about",
+				  "");
+
+		testRegex("Event Url ", r,
+				  "secondlife:///app/event/700727/about",
+				  "secondlife:///app/event/700727/about");
+
+		testRegex("Event Url in text", r,
+				  "XXX secondlife:///app/event/700727/about XXX",
+				  "secondlife:///app/event/700727/about");
+
+		testRegex("Event Url multicase", r,
+				  "XXX secondlife:///APP/Event/700727/about XXX",
+				  "secondlife:///APP/Event/700727/about");
+	}
+
+	template<> template<>
+	void object::test<7>()
+	{
+		//
+		// test LLUrlEntryClassified - secondlife://app/classified Urls
+		//
+		LLUrlEntryClassified url;
+		boost::regex r = url.getPattern();
+
+		testRegex("Invalid Classified Url", r,
+				  "secondlife:///app/classified/00128854-XXXX-5649-7ca6-5dfaa7514ab2/about",
+				  "");
+
+		testRegex("Classified Url ", r,
+				  "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about",
+				  "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about");
+
+		testRegex("Classified Url in text", r,
+				  "XXX secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about XXX",
+				  "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about");
+
+		testRegex("Classified Url multicase", r,
+				  "XXX secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About XXX",
+				  "secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About");
+	}
+
+	template<> template<>
+	void object::test<8>()
+	{
+		//
+		// test LLUrlEntryParcel - secondlife://app/parcel Urls
+		//
+		LLUrlEntryParcel url;
+		boost::regex r = url.getPattern();
+
+		testRegex("Invalid Classified Url", r,
+				  "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about",
+				  "");
+
+		testRegex("Classified Url ", r,
+				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about",
+				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about");
+
+		testRegex("Classified Url in text", r,
+				  "XXX secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about XXX",
+				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about");
+
+		testRegex("Classified Url multicase", r,
+				  "XXX secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About XXX",
+				  "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About");
+	}
+	template<> template<>
+	void object::test<9>()
+	{
+		//
+		// test LLUrlEntryTeleport - secondlife://app/teleport URLs
+		//
+		LLUrlEntryTeleport url;
+		boost::regex r = url.getPattern();
+
+		testRegex("no valid teleport [1]", r,
+				  "http://slurl.com/secondlife/Ahern/50/50/50/",
+				  "");
+
+		testRegex("no valid teleport [2]", r,
+				  "secondlife:///app/teleport/",
+				  "");
+
+		testRegex("no valid teleport [3]", r,
+				  "second-life:///app/teleport/Ahern/50/50/50/",
+				  "");
+
+		testRegex("no valid teleport [3]", r,
+				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",
+				  "");
+
+		testRegex("Ahern (50,50,50) [1]", r,
+				  "secondlife:///app/teleport/Ahern/50/50/50/",
+				  "secondlife:///app/teleport/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [2]", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [3]", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/50 XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/50");
+
+		testRegex("Ahern (50,50,50) multicase", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50) [1]", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/ XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/");
+
+		testRegex("Ahern (50,50) [2]", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50 XXX",
+				  "secondlife:///app/teleport/Ahern/50/50");
+
+		testRegex("Ahern (50)", r,
+				  "XXX secondlife:///app/teleport/Ahern/50 XXX",
+				  "secondlife:///app/teleport/Ahern/50");
+
+		testRegex("Ahern", r,
+				  "XXX secondlife:///app/teleport/Ahern/ XXX",
+				  "secondlife:///app/teleport/Ahern/");
+
+		testRegex("Ahern teleport with title", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!");
+
+		testRegex("Ahern teleport with msg", r,
+				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here. XXX",
+				  "secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here.");
+
+		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
+		testRegex("Teleport with brackets", r,
+				  "XXX secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30 XXX",
+				  "secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30");
+
+		// DEV-35459: SLURLs and teleport Links not parsed properly
+		testRegex("Teleport url with quote", r,
+				  "XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX",
+				  "secondlife:///app/teleport/A'ksha%20Oasis/41/166/701");
+	}
+
+	template<> template<>
+	void object::test<10>()
+	{
+		//
+		// test LLUrlEntrySL - general secondlife:// URLs
+		//
+		LLUrlEntrySL url;
+		boost::regex r = url.getPattern();
+
+		testRegex("no valid slapp [1]", r,
+				  "http:///app/",
+				  "");
+
+		testRegex("valid slapp [1]", r,
+				  "secondlife:///app/",
+				  "secondlife:///app/");
+
+		testRegex("valid slapp [2]", r,
+				  "secondlife:///app/teleport/Ahern/50/50/50/",
+				  "secondlife:///app/teleport/Ahern/50/50/50/");
+
+		testRegex("valid slapp [3]", r,
+				  "secondlife:///app/foo",
+				  "secondlife:///app/foo");
+
+		testRegex("valid slapp [4]", r,
+				  "secondlife:///APP/foo?title=Hi%20There",
+				  "secondlife:///APP/foo?title=Hi%20There");
+
+		testRegex("valid slapp [5]", r,
+				  "secondlife://host/app/",
+				  "secondlife://host/app/");
+
+		testRegex("valid slapp [6]", r,
+				  "secondlife://host:8080/foo/bar",
+				  "secondlife://host:8080/foo/bar");
+	}
+
+	template<> template<>
+	void object::test<11>()
+	{
+		//
+		// test LLUrlEntrySLLabel - general secondlife:// URLs with labels
+		//
+		LLUrlEntrySLLabel url;
+		boost::regex r = url.getPattern();
+
+		testRegex("invalid wiki url [1]", r,
+				  "[secondlife:///app/]",
+				  "");
+
+		testRegex("invalid wiki url [2]", r,
+				  "[secondlife:///app/",
+				  "");
+
+		testRegex("invalid wiki url [3]", r,
+				  "[secondlife:///app/ Label",
+				  "");
+
+		testRegex("agent slurl with label (spaces)", r,
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  Text]",
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  Text]");
+
+		testRegex("agent slurl with label (tabs)", r,
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]",
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]");
+
+		testRegex("agent slurl with label", r,
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]",
+				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]");
+
+		testRegex("teleport slurl with label", r,
+				  "XXX [secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern] YYY",
+				  "[secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern]");
+	}
+}
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4dae49db903d4a6bc1506ba7ffdf2fd18c6aa7b8
--- /dev/null
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -0,0 +1,177 @@
+/**
+ * @file llurlmatch_test.cpp
+ * @author Martin Reddy
+ * @brief Unit tests for LLUrlMatch
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
+ * this source code is governed by the Linden Lab Source Code Disclosure
+ * Agreement ("Agreement") previously entered between you and Linden
+ * Lab. By accessing, using, copying, modifying or distributing this
+ * software, you acknowledge that you have been informed of your
+ * obligations under the Agreement 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 "../llurlmatch.h"
+#include "lltut.h"
+
+namespace tut
+{
+	struct LLUrlMatchData
+	{
+	};
+
+	typedef test_group<LLUrlMatchData> factory;
+	typedef factory::object object;
+}
+
+namespace
+{
+	tut::factory tf("LLUrlMatch");
+}
+
+namespace tut
+{
+	template<> template<>
+	void object::test<1>()
+	{
+		//
+		// test the empty() method
+		//
+		LLUrlMatch match;
+		ensure("empty()", match.empty());
+
+		match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", "", "");
+		ensure("! empty()", ! match.empty());
+	}
+
+	template<> template<>
+	void object::test<2>()
+	{
+		//
+		// test the getStart() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getStart() == 0", match.getStart(), 0);
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getStart() == 10", match.getStart(), 10);
+	}
+
+	template<> template<>
+	void object::test<3>()
+	{
+		//
+		// test the getEnd() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getEnd() == 0", match.getEnd(), 0);
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getEnd() == 20", match.getEnd(), 20);
+	}
+
+	template<> template<>
+	void object::test<4>()
+	{
+		//
+		// test the getUrl() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getUrl() == ''", match.getUrl(), "");
+
+		match.setValues(10, 20, "http://slurl.com/", "", "", "", "", "");
+		ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getUrl() == '' (2)", match.getUrl(), "");
+	}
+
+	template<> template<>
+	void object::test<5>()
+	{
+		//
+		// test the getLabel() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getLabel() == ''", match.getLabel(), "");
+
+		match.setValues(10, 20, "", "Label", "", "", "", "");
+		ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getLabel() == '' (2)", match.getLabel(), "");
+	}
+
+	template<> template<>
+	void object::test<6>()
+	{
+		//
+		// test the getTooltip() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getTooltip() == ''", match.getTooltip(), "");
+
+		match.setValues(10, 20, "", "", "Info", "", "", "");
+		ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getTooltip() == '' (2)", match.getTooltip(), "");
+	}
+
+	template<> template<>
+	void object::test<7>()
+	{
+		//
+		// test the getIcon() method
+		//
+		LLUrlMatch match;
+		ensure_equals("getIcon() == ''", match.getIcon(), "");
+
+		match.setValues(10, 20, "", "", "", "Icon", "", "");
+		ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure_equals("getIcon() == '' (2)", match.getIcon(), "");
+	}
+
+	template<> template<>
+	void object::test<8>()
+	{
+		//
+		// test the getMenuName() method
+		//
+		LLUrlMatch match;
+		ensure("getMenuName() empty", match.getMenuName().empty());
+
+		match.setValues(10, 20, "", "", "", "Icon", "xui_file.xml", "");
+		ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure("getMenuName() empty (2)", match.getMenuName().empty());
+	}
+
+	template<> template<>
+	void object::test<9>()
+	{
+		//
+		// test the getLocation() method
+		//
+		LLUrlMatch match;
+		ensure("getLocation() empty", match.getLocation().empty());
+
+		match.setValues(10, 20, "", "", "", "Icon", "xui_file.xml", "Paris");
+		ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris");
+
+		match.setValues(10, 20, "", "", "", "", "", "");
+		ensure("getLocation() empty (2)", match.getLocation().empty());
+	}
+}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b5e4259f89756e5557d0bef6d003516dfca9b6bb..767f93cf45c7192c3bc1912da9bb70eb7403b6a8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -66,7 +66,6 @@ include_directories(
 set(viewer_SOURCE_FILES
     llaccordionctrltab.cpp
     llaccordionctrl.cpp
-    llactiveimwindow.cpp
     llagent.cpp
     llagentaccess.cpp
     llagentdata.cpp
@@ -181,7 +180,6 @@ set(viewer_SOURCE_FILES
     llfloaterlandholdings.cpp
     llfloatermap.cpp
     llfloatermemleak.cpp
-    llfloatermute.cpp
     llfloaternamedesc.cpp
     llfloaternotificationsconsole.cpp
     llfloateropenobject.cpp
@@ -287,6 +285,7 @@ set(viewer_SOURCE_FILES
     llpanelavatar.cpp
     llpanelavatarrow.cpp
     llpanelavatartag.cpp
+    llpanelblockedlist.cpp
     llpanelclassified.cpp
     llpanelcontents.cpp
     llpaneldirbrowser.cpp
@@ -349,6 +348,8 @@ set(viewer_SOURCE_FILES
     llremoteparcelrequest.cpp
     llsavedsettingsglue.cpp
     llscreenchannel.cpp
+    llsearchcombobox.cpp
+    llsearchhistory.cpp
     llselectmgr.cpp
     llsidetray.cpp
     llsidetraypanelcontainer.cpp
@@ -518,7 +519,6 @@ set(viewer_HEADER_FILES
     ViewerInstall.cmake
     llaccordionctrltab.h
     llaccordionctrl.h
-    llactiveimwindow.h
     llagent.h
     llagentaccess.h
     llagentdata.h
@@ -636,7 +636,6 @@ set(viewer_HEADER_FILES
     llfloaterlandholdings.h
     llfloatermap.h
     llfloatermemleak.h
-    llfloatermute.h
     llfloaternamedesc.h
     llfloaternotificationsconsole.h
     llfloateropenobject.h
@@ -740,6 +739,7 @@ set(viewer_HEADER_FILES
     llpanelavatar.h
     llpanelavatarrow.h
     llpanelavatartag.h
+    llpanelblockedlist.h
     llpanelclassified.h
     llpanelcontents.h
     llpaneldirbrowser.h
@@ -804,6 +804,8 @@ set(viewer_HEADER_FILES
     llrootview.h
     llscreenchannel.h
     llsavedsettingsglue.h
+    llsearchcombobox.h
+    llsearchhistory.h
     llselectmgr.h
     llsidetray.h
     llsidetraypanelcontainer.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 2a08f62bb46aabb4e9c3f5a34a886715e59dd803..32b1443157341cc97a5d9a961d3fe35dcb4a3355 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -804,28 +804,6 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
-    <key>BuildBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>BuildBtnEnabled</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>BuildFeathering</key>
     <map>
       <key>Comment</key>
@@ -2784,17 +2762,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>FirstPersonBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>FirstRunThisInstall</key>
     <map>
       <key>Comment</key>
@@ -2966,28 +2933,6 @@
         <integer>0</integer>
       </array>
     </map>
-    <key>FlyBtnEnabled</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
-    <key>FlyBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>FlycamAbsolute</key>
     <map>
       <key>Comment</key>
@@ -4600,17 +4545,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>MouselookBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>MuteAmbient</key>
     <map>
       <key>Comment</key>
@@ -6552,17 +6486,6 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
-    <key>RunBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>RunMultipleThreads</key>
     <map>
       <key>Comment</key>
@@ -6943,10 +6866,10 @@
       <key>Value</key>
       <integer>0</integer>
     </map>    
-    <key>ShowPGSearchAll</key>    
+    <key>ShowCameraAndMoveControls</key>                
     <map>
       <key>Comment</key>
-      <string>Show/Hide Navigation Bar Favorites Panel</string>
+      <string>Show/Hide Camera and Move controls in the bottom tray</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6957,7 +6880,7 @@
     <key>ShowNavbarFavoritesPanel</key>    
     <map>
       <key>Comment</key>
-      <string>Show/Hide Navigation Bar Navigation Panel</string>
+      <string>Show/Hide Navigation Bar Favorites Panel</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6966,6 +6889,17 @@
       <integer>1</integer>   
     </map>
     <key>ShowNavbarNavigationPanel</key>        
+    <map>
+      <key>Comment</key>
+      <string>Show/Hide Navigation Bar Navigation Panel</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>   
+    </map>
+    <key>ShowPGSearchAll</key>    
     <map>
       <key>Comment</key>
       <string>Display results of search All that are flagged as PG</string>
@@ -7386,17 +7320,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>SitBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>SkinCurrent</key>
     <map>
       <key>Comment</key>
@@ -7757,17 +7680,6 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
-    <key>ThirdPersonBtnState</key>
-    <map>
-      <key>Comment</key>
-      <string />
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>ThrottleBandwidthKBPS</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 214065f08003b1b6c5d76415e739622b30f0cd97..08681db6cb63f436d42c4bf6fe56de98b87cf2a6 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -47,7 +47,6 @@
 #include "llfloaterdirectory.h"
 
 #include "llfloaterland.h"
-#include "llfloatermute.h"
 #include "llfloatersnapshot.h"
 #include "llfloatertools.h"
 #include "llfloaterworldmap.h"
@@ -795,12 +794,10 @@ void LLAgent::setFlying(BOOL fly)
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
 		}
 		setControlFlags(AGENT_CONTROL_FLY);
-		gSavedSettings.setBOOL("FlyBtnState", TRUE);
 	}
 	else
 	{
 		clearControlFlags(AGENT_CONTROL_FLY);
-		gSavedSettings.setBOOL("FlyBtnState", FALSE);
 	}
 
 
@@ -3998,11 +3995,6 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
 
 	LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
 
-	gSavedSettings.setBOOL("FirstPersonBtnState",	FALSE);
-	gSavedSettings.setBOOL("MouselookBtnState",		TRUE);
-	gSavedSettings.setBOOL("ThirdPersonBtnState",	FALSE);
-	gSavedSettings.setBOOL("BuildBtnState",			FALSE);
-
 	if (mAvatarObject.notNull())
 	{
 		mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
@@ -4098,11 +4090,6 @@ void LLAgent::changeCameraToFollow(BOOL animate)
 			mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
 		}
 
-		gSavedSettings.setBOOL("FirstPersonBtnState",	FALSE);
-		gSavedSettings.setBOOL("MouselookBtnState",		FALSE);
-		gSavedSettings.setBOOL("ThirdPersonBtnState",	TRUE);
-		gSavedSettings.setBOOL("BuildBtnState",			FALSE);
-
 		// unpause avatar animation
 		mPauseRequest = NULL;
 
@@ -4149,11 +4136,6 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
 		mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
 	}
 
-	gSavedSettings.setBOOL("FirstPersonBtnState",	FALSE);
-	gSavedSettings.setBOOL("MouselookBtnState",		FALSE);
-	gSavedSettings.setBOOL("ThirdPersonBtnState",	TRUE);
-	gSavedSettings.setBOOL("BuildBtnState",			FALSE);
-
 	LLVector3 at_axis;
 
 	// unpause avatar animation
@@ -4231,11 +4213,6 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
 		LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
 	}
 
-	gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
-	gSavedSettings.setBOOL("MouselookBtnState", FALSE);
-	gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE);
-	gSavedSettings.setBOOL("BuildBtnState", FALSE);
-
 	if (camera_animate)
 	{
 		startCameraAnimation();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index de4f7ab0912e799cd65f637c465c8a496b0de639..800c55511368e980f5416c622a541b5671681743 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -80,6 +80,7 @@
 
 // Linden library includes
 #include "llmemory.h"
+#include "llurlaction.h"
 
 // Third party library includes
 #include <boost/bind.hpp>
@@ -685,9 +686,14 @@ bool LLAppViewer::init()
 	LLTransUtil::parseLanguageStrings("language_settings.xml");
 	LLWeb::initClass();			  // do this after LLUI
 
-	LLTextEditor::setURLCallbacks(&LLWeb::loadURL,
-				&LLURLDispatcher::dispatchFromTextEditor,
-				&LLURLDispatcher::dispatchFromTextEditor);
+	// Provide the text fields with callbacks for opening Urls
+	LLUrlAction::setOpenURLCallback(&LLWeb::loadURL);
+	LLUrlAction::setOpenURLInternalCallback(&LLWeb::loadURLInternal);
+	LLUrlAction::setOpenURLExternalCallback(&LLWeb::loadURLExternal);
+	LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
+
+	// Set the link color for any Urls in text fields
+	LLTextBase::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") );
 
 	// Load translations for tooltips
 	LLFloater::initClass();
@@ -2316,12 +2322,6 @@ void LLAppViewer::cleanupSavedSettings()
 {
 	gSavedSettings.setBOOL("MouseSun", FALSE);
 
-	gSavedSettings.setBOOL("FlyBtnState", FALSE);
-
-	gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
-	gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE);
-	gSavedSettings.setBOOL("BuildBtnState", FALSE);
-
 	gSavedSettings.setBOOL("UseEnergy", TRUE);				// force toggle to turn off, since sends message to simulator
 
 	gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index f557adf6a6a6308e7594bd12d4798d1d097b0c43..a121d327f788220194bfea3fb57f581b97a46652 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -62,6 +62,9 @@ LLAvatarList::LLAvatarList(const Params& p)
 {
 	setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params
 
+	// display a context menu appropriate for a list of avatar names
+	setContextMenu(LLScrollListCtrl::MENU_AVATAR);
+
     // "volume" column
     {
     	LLScrollListColumn::Params col_params;
@@ -220,6 +223,16 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 #endif
 	setScrollPos(pos);
 
+	updateLineHeight();
+	LLRect	rect = getRequiredRect();
+
+	LLSD params;
+	params["action"] = "size_changes";
+	params["width"] = rect.getWidth();
+	params["height"] = llmax(rect.getHeight(),20) + 5;
+
+	getParent()->notifyParent(params);
+
 	return have_names;
 }
 
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 2403e891f68db6b178f9c7ca2c92d5f58039bbf7..861f23abb7132fad27fbdd3cdba22d26022bfb47 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,13 +40,12 @@
 #include "lllayoutstack.h"
 #include "llnearbychatbar.h"
 #include "llsplitbutton.h"
+#include "llsyswellwindow.h"
 #include "llfloatercamera.h"
 #include "llimpanel.h"
-#include "llactiveimwindow.h"
 
 LLBottomTray::LLBottomTray(const LLSD&)
 :	mChicletPanel(NULL),
-	mIMWell(NULL),
 	mSysWell(NULL),
 	mTalkBtn(NULL),
 	mNearbyChatBar(NULL),
@@ -58,10 +57,10 @@ LLBottomTray::LLBottomTray(const LLSD&)
 	LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");
 
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
-	mIMWell = getChild<LLNotificationChiclet>("im_well");
 	mSysWell = getChild<LLNotificationChiclet>("sys_well");
 
 	mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window"));
+
 	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
 
 	LLSplitButton* presets = getChild<LLSplitButton>("presets");
@@ -76,14 +75,20 @@ LLBottomTray::LLBottomTray(const LLSD&)
 
 	// Necessary for focus movement among child controls
 	setFocusRoot(TRUE);
-
-	LLActiveIMWindow::init(mIMWell);
 }
 
 BOOL LLBottomTray::postBuild()
 {
+	mCommitCallbackRegistrar.add("ShowCamMoveCtrls.Action", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked, this, _2));
+	mEnableCallbackRegistrar.add("ShowCamMoveCtrls.EnableMenuItem", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled, this, _2));
+
+	mShowCamMoveCtrlsContextMenu =  LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_camera_move_controls.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	gMenuHolder->addChild(mShowCamMoveCtrlsContextMenu);
+
 	mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
+	mMovementPanel = getChild<LLPanel>("movement_panel");
+	mCamPanel = getChild<LLPanel>("cam_panel");
 
 	return TRUE;
 }
@@ -119,6 +124,34 @@ void* LLBottomTray::createNearbyChatBar(void* userdata)
 	return new LLNearbyChatBar();
 }
 
+LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
+{
+	if(session_id.isNull())
+	{
+		return NULL;
+	}
+
+	LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id);
+	if (!im) 
+	{
+		return NULL; //should never happen
+	}
+
+	switch(im->getDialogType())
+	{
+	case IM_NOTHING_SPECIAL:
+		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
+		break;
+	case IM_SESSION_GROUP_START:
+	case IM_SESSION_INVITE:
+		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
+		break;
+	default:
+		return NULL;
+		break;
+	}
+}
+
 //virtual
 void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
@@ -130,12 +163,18 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam
 		}
 		else
 		{
-			LLIMChiclet* chiclet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
-			chiclet->setIMSessionName(name);
-			chiclet->setOtherParticipantId(other_participant_id);
+			LLIMChiclet* chiclet = createIMChiclet(session_id);
+			if(chiclet)
+			{
+				chiclet->setIMSessionName(name);
+				chiclet->setOtherParticipantId(other_participant_id);
+			}
+			else
+			{
+				llerrs << "Could not create chiclet" << llendl;
+			}
 		}
 	}
-	updateImChicletCount();
 }
 
 //virtual
@@ -145,7 +184,6 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id)
 	{
 		getChicletPanel()->removeChiclet(session_id);
 	}
-	updateImChicletCount();
 }
 
 //virtual
@@ -174,8 +212,9 @@ void LLBottomTray::setVisible(BOOL visible)
 			child_it != mToolbarStack->getChildList()->end(); child_it++)
 		{
 			LLView* viewp = *child_it;
+			std::string name = viewp->getName();
 			
-			if ("chat_bar" == viewp->getName())
+			if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name)
 				continue;
 			else 
 			{
@@ -185,7 +224,45 @@ void LLBottomTray::setVisible(BOOL visible)
 	}
 }
 
-void LLBottomTray::updateImChicletCount() {
-	U32 chicletCount = mChicletPanel->getChicletCount();
-	mIMWell->setCounter(chicletCount);
+BOOL LLBottomTray::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (mShowCamMoveCtrlsContextMenu)
+	{
+		mShowCamMoveCtrlsContextMenu->buildDrawLabels();
+		mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y);
+	}
+
+	return TRUE;
+}
+
+bool LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "show_camera_move_controls")
+	{
+		return gSavedSettings.getBOOL("ShowCameraAndMoveControls");
+	}
+
+	return FALSE;
+}
+
+void LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "show_camera_move_controls")
+	{
+		BOOL state = !gSavedSettings.getBOOL("ShowCameraAndMoveControls");
+
+		showCameraAndMoveControls(state);
+		gSavedSettings.setBOOL("ShowCameraAndMoveControls", state);
+	}
+}
+
+void LLBottomTray::showCameraAndMoveControls(BOOL visible)
+{
+	mCamPanel->setVisible(visible);
+	mMovementPanel->setVisible(visible);
 }
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 7f606339bc04cfba58ce0f4a48e966326c23a95a..c3c840ede0921d49c093beed54ef294e4f2e7af2 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -33,6 +33,8 @@
 #ifndef LL_LLBOTTOMPANEL_H
 #define LL_LLBOTTOMPANEL_H
 
+#include <llmenugl.h>
+
 #include "llpanel.h"
 #include "llimview.h"
 
@@ -42,6 +44,7 @@ class LLLayoutStack;
 class LLNotificationChiclet;
 class LLTalkButton;
 class LLNearbyChatBar;
+class LLIMChiclet;
 
 class LLBottomTray 
 	: public LLSingleton<LLBottomTray>
@@ -55,7 +58,6 @@ class LLBottomTray
 	BOOL postBuild();
 
 	LLChicletPanel*		getChicletPanel()	{return mChicletPanel;}
-	LLNotificationChiclet*	getIMWell()	{return mIMWell;}
 	LLNotificationChiclet*	getSysWell()	{return mSysWell;}
 	LLNearbyChatBar*		getNearbyChatBar()	{return mNearbyChatBar;}
 
@@ -68,8 +70,11 @@ class LLBottomTray
 	virtual void onFocusLost();
 	virtual void setVisible(BOOL visible);
 
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	void showCameraAndMoveControls(BOOL visible);
+
 private:
-	void updateImChicletCount();
 
 protected:
 
@@ -77,15 +82,24 @@ class LLBottomTray
 
 	void onChicletClick(LLUICtrl* ctrl);
 
+	bool onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata);
+	void onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata);
+
 	static void* createNearbyChatBar(void* userdata);
 
+	/**
+	 * Creates IM Chiclet based on session type (IM chat or Group chat)
+	 */
+	LLIMChiclet* createIMChiclet(const LLUUID& session_id);
+
 	LLChicletPanel* 	mChicletPanel;
-	LLNotificationChiclet* 	mIMWell;
 	LLNotificationChiclet* 	mSysWell;
 	LLTalkButton* 		mTalkBtn;
 	LLNearbyChatBar*	mNearbyChatBar;
 	LLLayoutStack*		mToolbarStack;
-
+	LLMenuGL*			mShowCamMoveCtrlsContextMenu;
+	LLPanel*			mMovementPanel;
+	LLPanel*			mCamPanel;
 };
 
 #endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index 9399e1f68d7ea6d68a848035d7e4d60043848bb0..e6398dd47aba2f64e8a16ac2c0447dfacdc4fc13 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -1,10 +1,11 @@
 /** 
  * @file llchatmsgbox.cpp
+ * @author Martin Reddy
  * @brief chat history text box, able to show array of strings with separator
  *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
  * 
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
  * 
  * Second Life Viewer Source Code
  * The source code in this file ("Source Code") is provided by Linden Lab
@@ -30,360 +31,96 @@
  * $/LicenseInfo$
  */
 
-
 #include "llviewerprecompiledheaders.h"
 
 #include "llchatmsgbox.h"
 #include "llwindow.h"
-#include "llfocusmgr.h"
-
-static LLDefaultChildRegistry::Register<LLChatMsgBox> r("text_chat");
 
-LLChatMsgBox::Params::Params()
-:	text_color("text_color"),
-	highlight_on_hover("hover", false),
-	border_visible("border_visible", false),
-	border_drop_shadow_visible("border_drop_shadow_visible", false),
-	bg_visible("bg_visible", false),
-	use_ellipses("use_ellipses"),
-	word_wrap("word_wrap", false),
-	hover_color("hover_color"),
-	disabled_color("disabled_color"),
-	background_color("background_color"),
-	border_color("border_color"),
-	line_spacing("line_spacing", 4),
-	block_spacing("block_spacing",10),
-	text("text"),
-	font_shadow("font_shadow", LLFontGL::NO_SHADOW)
-{}
 
-LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)
-:	LLUICtrl(p),
-    mFontGL(p.font),
-	mHoverActive( p.highlight_on_hover ),
-	mHasHover( FALSE ),
-	mBackgroundVisible( p.bg_visible ),
-	mBorderVisible( p.border_visible ),
-	mShadowType( p.font_shadow ),
-	mBorderDropShadowVisible( p.border_drop_shadow_visible ),
-	mUseEllipses( p.use_ellipses ),
-	mVAlign( LLFontGL::TOP ),
-	mClickedCallback(NULL),
-	mTextColor(p.text_color()),
-	mDisabledColor(p.disabled_color()),
-	mBackgroundColor(p.background_color()),
-	mBorderColor(p.border_color()),
-	mHoverColor(p.hover_color()),
-	mHAlign(p.font_halign),
-	mLineSpacing(p.line_spacing),
-	mBlockSpasing(p.block_spacing),
-	mWordWrap( p.word_wrap ),
-	mFontStyle(LLFontGL::getStyleFromString(p.font.style))
-{
-	setText( p.text() );
-}
+static LLDefaultChildRegistry::Register<LLChatMsgBox> r("text_chat");
 
-BOOL LLChatMsgBox::handleMouseDown(S32 x, S32 y, MASK mask)
+LLChatMsgBox::Params::Params() :
+	block_spacing("block_spacing", 10)
 {
-	BOOL	handled = FALSE;
-
-	// HACK: Only do this if there actually is a click callback, so that
-	// overly large text boxes in the older UI won't start eating clicks.
-	if (mClickedCallback)
-	{
-		handled = TRUE;
-
-		// Route future Mouse messages here preemptively.  (Release on mouse up.)
-		gFocusMgr.setMouseCapture( this );
-		
-		if (getSoundFlags() & MOUSE_DOWN)
-		{
-			make_ui_sound("UISndClick");
-		}
-	}
-
-	return handled;
+	line_spacing = 4;
 }
 
-BOOL LLChatMsgBox::handleMouseUp(S32 x, S32 y, MASK mask)
-{
-	BOOL	handled = FALSE;
-
-	// We only handle the click if the click both started and ended within us
-
-	// HACK: Only do this if there actually is a click callback, so that
-	// overly large text boxes in the older UI won't start eating clicks.
-	if (mClickedCallback
-		&& hasMouseCapture())
-	{
-		handled = TRUE;
-
-		// Release the mouse
-		gFocusMgr.setMouseCapture( NULL );
-
-		if (getSoundFlags() & MOUSE_UP)
-		{
-			make_ui_sound("UISndClickRelease");
-		}
-
-		// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
-		// If mouseup in the widget, it's been clicked
-		if (mClickedCallback)
-		{
-			mClickedCallback();
-		}
-	}
-
-	return handled;
-}
+LLChatMsgBox::LLChatMsgBox(const Params& p) :
+	LLTextBox(p),
+	mBlockSpacing(p.block_spacing)
+{}
 
-BOOL LLChatMsgBox::handleHover(S32 x, S32 y, MASK mask)
+void LLChatMsgBox::addText( const LLStringExplicit& text )
 {
-	BOOL handled = LLView::handleHover(x,y,mask);
-	if(mHoverActive)
+	LLWString t = mText.getWString();
+	if (! t.empty())
 	{
-		mHasHover = TRUE; // This should be set every frame during a hover.
-		getWindow()->setCursor(UI_CURSOR_ARROW);
+		t += '\n';
 	}
-
-	return (handled || mHasHover);
-}
-
-void	LLChatMsgBox::addText( const LLStringExplicit& text )
-{
-	boost::shared_ptr<text_block> t(new text_block());
-	t->text = wrapText(text);
-	setLineLengths(*t);
-	mTextStrings.push_back(t);
+	t += getWrappedText(text);
+	LLTextBox::setText(wstring_to_utf8str(t));
+	mSeparatorOffset.push_back(getLength());
 }
 
 void LLChatMsgBox::setText(const LLStringExplicit& text)
 {
-	mTextStrings.clear();
-
+	mSeparatorOffset.clear();
+	mText.clear();
 	addText(text);
-
-}
-
-void LLChatMsgBox::resetLineLengths()
-{
-	for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
-			it!=mTextStrings.end();++it)
-	{
-		boost::shared_ptr<text_block> tblock = *it;
-		setLineLengths(*tblock);
-	}
-}
-
-void LLChatMsgBox::setLineLengths(text_block& t)
-{
-	t.lines.clear();
-	
-	std::string::size_type  cur = 0;
-	std::string::size_type  len = t.text.length();
-
-	while (cur < len) 
-	{
-		std::string::size_type end = t.text.getWString().find('\n', cur);
-		std::string::size_type runLen;
-		
-		if (end == std::string::npos)
-		{
-			runLen = len - cur;
-			cur = len;
-		}
-		else
-		{
-			runLen = end - cur;
-			cur = end + 1; // skip the new line character
-		}
-
-		t.lines.push_back( (S32)runLen );
-	}
 }
 
-std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_width)
-{
-	if (max_width < 0.0f)
-	{
-		max_width = (F32)getRect().getWidth();
-	}
-
-	LLWString wtext = utf8str_to_wstring(in_text);
-	LLWString final_wtext;
-
-	LLWString::size_type  cur = 0;;
-	LLWString::size_type  len = wtext.size();
-	while (cur < len)
-	{
-		LLWString::size_type end = wtext.find('\n', cur);
-		if (end == LLWString::npos)
-		{
-			end = len;
-		}
-		
-		LLWString::size_type runLen = end - cur;
-		if (runLen > 0)
-		{
-			LLWString run(wtext, cur, runLen);
-			LLWString::size_type useLen =
-				mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE);
-
-			final_wtext.append(wtext, cur, useLen);
-			cur += useLen;
-			// not enough room to add any more characters
-			if (useLen == 0) break;
-		}
-
-		if (cur < len)
-		{
-			if (wtext[cur] == '\n')
-				cur += 1;
-			else
-				final_wtext += '\n';
-		}
-	}
-	
-	std::string final_text = wstring_to_utf8str(final_wtext);
-	return final_text;
-}
-
-S32	LLChatMsgBox::getTextLinesNum()
-{
-	S32 num_lines = 0;
-	for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
-			it!=mTextStrings.end();++it)
-	{
-		boost::shared_ptr<text_block> tblock = *it;
-		num_lines+=tblock->lines.size();
-	}
-
-	if( num_lines < 1 )
-	{
-		num_lines = 1;
-	}
-
-	return num_lines;
+void LLChatMsgBox::setValue(const LLSD& value )
+{ 
+	setText(value.asString());
 }
 
 S32 LLChatMsgBox::getTextPixelHeight()
 {
+	S32 num_blocks = mSeparatorOffset.size();
 	S32 num_lines = getTextLinesNum();
-	return (S32)(num_lines * mFontGL->getLineHeight() +  (num_lines-1)*mLineSpacing + mBlockSpasing*(mTextStrings.size()-1) + 2*mLineSpacing);//some extra space
-}
-
-void LLChatMsgBox::setValue(const LLSD& value )
-{ 
-	setText(value.asString());
+	return (S32)(num_lines * mDefaultFont->getLineHeight() + \
+				 (num_lines-1) * mLineSpacing + \
+				 (num_blocks-1) * mBlockSpacing + \
+				 2 * mLineSpacing);
 }
 
-
-void LLChatMsgBox::draw()
+S32 LLChatMsgBox::getTextLinesNum()
 {
-	if (mBorderVisible)
-	{
-		gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
-	}
-
-	if( mBorderDropShadowVisible )
+	S32 num_lines = getLineCount();
+	if (num_lines < 1)
 	{
-		static LLUICachedControl<LLColor4> color_drop_shadow ("ColorDropShadow", *(new LLColor4));
-		static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
-		gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
-			color_drop_shadow, drop_shadow_tooltip);
-	}
-
-	if (mBackgroundVisible)
-	{
-		LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
-		gl_rect_2d( r, mBackgroundColor.get() );
-	}
-
-	S32 text_x = 0;
-	switch( mHAlign )
-	{
-	case LLFontGL::LEFT:	
-		break;
-	case LLFontGL::HCENTER:
-		text_x = getRect().getWidth() / 2;
-		break;
-	case LLFontGL::RIGHT:
-		text_x = getRect().getWidth() ;
-		break;
-	}
-
-	S32 text_y = getRect().getHeight() ;
-
-	if ( getEnabled() )
-	{
-		if(mHasHover)
-		{
-			drawText( text_x, text_y, mHoverColor.get() );
-		}
-		else
-		{
-			drawText( text_x, text_y, mTextColor.get() );
-		}				
-	}
-	else
-	{
-		drawText( text_x, text_y, mDisabledColor.get() );
-	}
-
-	if (sDebugRects)
-	{
-		drawDebugRect();
+		num_lines = 1;
 	}
-
-	//// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
-	//std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
-	//if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
-	//{
-	//	drawDebugRect();
-	//}
-
-	mHasHover = FALSE; // This is reset every frame.
-}
-
-void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
-	// reparse line lengths
-	LLView::reshape(width, height, called_from_parent);
-	resetLineLengths();
+	
+	return num_lines;
 }
 
-void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )
+void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4 &color)
 {
+	S32 start = 0;
 	S32 width = getRect().getWidth()-10;
 
-	
-	for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
-			it!=mTextStrings.end();++it)
+	// iterate through each block of text that has been added
+	y -= mLineSpacing;
+	for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
 	{
-		boost::shared_ptr<text_block> tblock = *it;
+		// display the text for this block
+		S32 num_chars = *it - start;
+		LLWString text = mDisplayText.substr(start, num_chars);
+		LLTextBox::drawText(x, y, text, color);
 		
-		S32 cur_pos = 0;
-		for (std::vector<S32>::iterator iter = tblock->lines.begin();
-			iter != tblock->lines.end(); ++iter)
+		// exit the loop if this is the last text block
+		start += num_chars + 1;  // skip the newline
+		if (++it == mSeparatorOffset.end())
 		{
-			S32 line_length = *iter;
-			mFontGL->render(tblock->text, cur_pos, (F32)x, (F32)y, color,
-							mHAlign, mVAlign,
-							mFontStyle,
-							mShadowType,
-							line_length, getRect().getWidth(), NULL, mUseEllipses );
-			cur_pos += line_length + 1;
-			y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
-
-		}
-		std::vector< boost::shared_ptr<text_block> >::iterator next = it;
-		++next;
-		if(next == mTextStrings.end())
 			break;
-		//separator
-		gl_line_2d(5,y-mBlockSpasing/2,width,y-mBlockSpasing/2,LLColor4::grey);
-		y-=mBlockSpasing;
-	}
+		}
 
+		// output a separator line between blocks
+		S32 num_lines = std::count(text.begin(), text.end(), '\n') + 1;
+		y -= num_lines * (llfloor(mDefaultFont->getLineHeight()) + mLineSpacing);
+		S32 sep_y = y - mBlockSpacing/2 + mLineSpacing/2;
+		gl_line_2d(5, sep_y, width, sep_y, LLColor4::grey);
+		y -= mBlockSpacing;
+	}
 }
-
diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h
index 61035499c7c72826cc4b61656fbaa7813e0ce274..b81b740bdc6260f783e53a3b3cf8f7cb19459c47 100644
--- a/indra/newview/llchatmsgbox.h
+++ b/indra/newview/llchatmsgbox.h
@@ -1,10 +1,11 @@
 /** 
  * @file llchatmsgbox.h
+ * @author Martin Reddy
  * @brief chat history text box, able to show array of strings with separator
  *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
  * 
- * Copyright (c) 2004-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
  * 
  * Second Life Viewer Source Code
  * The source code in this file ("Source Code") is provided by Linden Lab
@@ -33,127 +34,45 @@
 #ifndef LL_LLCHATMSGBOX_H
 #define LL_LLCHATMSGBOX_H
 
-
+#include "lltextbox.h"
 #include "lluictrl.h"
 #include "v4color.h"
 #include "llstring.h"
-#include "lluistring.h"
-
 
-class LLChatMsgBox
-:	public LLUICtrl
+///
+/// LLChatMsgBox provides a text box with support for multiple blocks
+/// of text that can be added incrementally. Each block of text is
+/// visual separated from the previous block (e.g., with a horizontal
+/// line).
+///
+class LLChatMsgBox :
+	public LLTextBox
 {
-protected:
-	struct text_block
-	{
-		LLUIString			text;
-		std::vector<S32>	lines;
-	};
 public:
-	typedef boost::function<void (void)> callback_t;
-
-	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+	struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
 	{
-		Optional<std::string> text;
-
-		Optional<bool>		highlight_on_hover,
-							border_visible,
-							border_drop_shadow_visible,
-							bg_visible,
-							use_ellipses,
-							word_wrap;
-
-		Optional<LLFontGL::ShadowType>	font_shadow;
-
-		Optional<LLUIColor>	text_color,
-							hover_color,
-							disabled_color,
-							background_color,
-							border_color;
-
-		Optional<S32>		line_spacing;
-		
-		Optional<S32>		block_spacing;
+		Optional<S32>	block_spacing;
 
 		Params();
 	};
+
 protected:
 	LLChatMsgBox(const Params&);
 	friend class LLUICtrlFactory;
-public:
-	virtual void	draw();
-	virtual void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
-	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
-	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
-	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
-
-	void			setColor( const LLColor4& c )			{ mTextColor = c; }
-	void			setDisabledColor( const LLColor4& c)	{ mDisabledColor = c; }
-	void			setBackgroundColor( const LLColor4& c)	{ mBackgroundColor = c; }	
-	void			setBorderColor( const LLColor4& c)		{ mBorderColor = c; }	
-
-	void			setHoverColor( const LLColor4& c )		{ mHoverColor = c; }
-	void			setHoverActive( BOOL active )			{ mHoverActive = active; }
-
-	void			setText( const LLStringExplicit& text );
-	void			addText( const LLStringExplicit& text );
-	
-	void			setUseEllipses( BOOL use_ellipses )		{ mUseEllipses = use_ellipses; }
+public:
+	void				setText(const LLStringExplicit &text);
+	void				addText(const LLStringExplicit &text);
 	
-	void			setBackgroundVisible(BOOL visible)		{ mBackgroundVisible = visible; }
-	void			setBorderVisible(BOOL visible)			{ mBorderVisible = visible; }
-	void			setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
-	void			setRightAlign()							{ mHAlign = LLFontGL::RIGHT; }
-	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
-	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); }		// mouse down and up within button
-
-	const LLFontGL* getFont() const							{ return mFontGL; }
-
-	S32				getTextPixelHeight();
-	S32				getTextLinesNum();
-
-	virtual void	setValue(const LLSD& value );		
-
+	S32					getTextPixelHeight();
+	S32					getTextLinesNum();
 
+	/*virtual*/ void	setValue(const LLSD &value);
+	/*virtual*/ void	drawText(S32 x, S32 y, const LLWString &text, const LLColor4 &color);
 
 private:
-	std::string		wrapText			(const LLStringExplicit& in_text, F32 max_width = -1.0);
-
-	void			setLineLengths		(text_block& t);
-	void			resetLineLengths	();
-	void			drawText			(S32 x, S32 y, const LLColor4& color );
-
-	const LLFontGL*	mFontGL;
-	LLUIColor	mTextColor;
-	LLUIColor	mDisabledColor;
-	LLUIColor	mBackgroundColor;
-	LLUIColor	mBorderColor;
-	LLUIColor	mHoverColor;
-
-	BOOL			mHoverActive;	
-	BOOL			mHasHover;
-	BOOL			mBackgroundVisible;
-	BOOL			mBorderVisible;
-	BOOL			mWordWrap;
-	
-	U8				mFontStyle; // style bit flags for font
-	LLFontGL::ShadowType mShadowType;
-	BOOL			mBorderDropShadowVisible;
-	BOOL			mUseEllipses;
-
-	S32				mLineSpacing;
-	S32				mBlockSpasing;
-
-	LLFontGL::HAlign mHAlign;
-	LLFontGL::VAlign mVAlign;
-
-	callback_t		mClickedCallback;
-
-
-	//same as mLineLengthList and mText in LLTextBox
-	std::vector< boost::shared_ptr<text_block> > mTextStrings;
-
+	S32					mBlockSpacing;
+	std::vector<S32>	mSeparatorOffset;
 };
 
 #endif
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 6b4dfa73a469227eb1bf127bdf4b7943ad8c6f11..808fcde312c1539609c5a0462c72c0873cfd8e32 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -47,13 +47,11 @@
 #include "llvoicecontrolpanel.h"
 #include "llgroupmgr.h"
 
-static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu";
-static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu";
-
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
 static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
 static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im");
+static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t4("chiclet_im_p2p");
+static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t5("chiclet_im_group");
 
 S32 LLNotificationChiclet::mUreadSystemNotifications = 0;
 S32 LLNotificationChiclet::mUreadIMNotifications = 0;
@@ -119,6 +117,10 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(
 	return mButton->setClickedCallback(cb);
 }
 
+void LLNotificationChiclet::setToggleState(BOOL toggled) {
+	mButton->setToggleState(toggled);
+}
+
 void LLNotificationChiclet::updateUreadIMNotifications()
 {
 	mUreadIMNotifications = gIMMgr->getNumberOfUnreadIM();
@@ -187,9 +189,48 @@ void LLChiclet::setValue(const LLSD& value)
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLIMChiclet::Params::Params()
+LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p)
+: LLChiclet(p)
+{
+}
+
+void LLIMChiclet::onMouseDown()
+{
+	LLIMFloater::toggle(getSessionId());
+	setCounter(0);
+}
+
+BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	onMouseDown();
+	return LLChiclet::handleMouseDown(x, y, mask);
+}
+
+void LLIMChiclet::draw()
+{
+	LLUICtrl::draw();
+
+	//if we have a docked floater, we want to position it relative to us
+	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", getSessionId());
+
+	if (im_floater && im_floater->isDocked()) 
+	{
+		S32 x, y;
+		getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y);
+		im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom);	
+		//set this so the docked floater knows it's been positioned and can now draw
+		im_floater->setPositioned(true);
+	}
+
+	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLIMP2PChiclet::Params::Params()
 : avatar_icon("avatar_icon")
-, group_insignia("group_insignia")
 , unread_notifications("unread_notifications")
 , speaker("speaker")
 , show_speaker("show_speaker")
@@ -197,13 +238,8 @@ LLIMChiclet::Params::Params()
 	rect(LLRect(0, 25, 45, 0));
 
 	avatar_icon.name("avatar_icon");
-	avatar_icon.visible(false);
 	avatar_icon.rect(LLRect(0, 25, 25, 0));
-
-	//it's an icon for a group in case there is a group chat created
-	group_insignia.name("group_icon");
-	group_insignia.visible(false);
-	group_insignia.rect(LLRect(0, 25, 25, 0));
+	avatar_icon.mouse_opaque(false);
 
 	unread_notifications.name("unread");
 	unread_notifications.rect(LLRect(25, 25, 45, 0));
@@ -211,6 +247,7 @@ LLIMChiclet::Params::Params()
 	unread_notifications.font_halign(LLFontGL::HCENTER);
 	unread_notifications.v_pad(5);
 	unread_notifications.text_color(LLColor4::white);
+	unread_notifications.mouse_opaque(false);
 
 	speaker.name("speaker");
 	speaker.rect(LLRect(45, 25, 65, 0));
@@ -218,25 +255,16 @@ LLIMChiclet::Params::Params()
 	show_speaker = false;
 }
 
-LLIMChiclet::LLIMChiclet(const Params& p)
-: LLChiclet(p)
-, LLGroupMgrObserver(LLUUID())
-, mAvatarCtrl(NULL)
-, mGroupInsignia(NULL)
+LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
+: LLIMChiclet(p)
+, mChicletIconCtrl(NULL)
 , mCounterCtrl(NULL)
 , mSpeakerCtrl(NULL)
-, mShowSpeaker(p.show_speaker)
 , mPopupMenu(NULL)
 {
 	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
-	mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
-	addChild(mAvatarCtrl);
-
-	//Before setOtherParticipantId() we are UNAWARE which dialog type will it be
-	//so keeping both icons for all both p2p and group chat cases
-	LLIconCtrl::Params grop_icon_params = p.group_insignia;
-	mGroupInsignia = LLUICtrlFactory::create<LLIconCtrl>(grop_icon_params);
-	addChild(mGroupInsignia);
+	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
+	addChild(mChicletIconCtrl);
 
 	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
 	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
@@ -249,16 +277,10 @@ LLIMChiclet::LLIMChiclet(const Params& p)
 	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
 	addChild(mSpeakerCtrl);
 
-	setShowSpeaker(getShowSpeaker());
-}
-
-LLIMChiclet::~LLIMChiclet()
-{
-	LLGroupMgr::getInstance()->removeObserver(this);
+	setShowSpeaker(p.show_speaker);
 }
 
-
-void LLIMChiclet::setCounter(S32 counter)
+void LLIMP2PChiclet::setCounter(S32 counter)
 {
 	mCounterCtrl->setCounter(counter);
 
@@ -279,15 +301,9 @@ void LLIMChiclet::setCounter(S32 counter)
 	}
 }
 
-void LLIMChiclet::onMouseDown()
-{
-	LLIMFloater::toggle(getSessionId());
-	setCounter(0);
-}
-
-LLRect LLIMChiclet::getRequiredRect()
+LLRect LLIMP2PChiclet::getRequiredRect()
 {
-	LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0);
+	LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
 	if(getShowCounter())
 	{
 		rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
@@ -299,169 +315,234 @@ LLRect LLIMChiclet::getRequiredRect()
 	return rect;
 }
 
-void LLIMChiclet::setShowCounter(bool show)
+void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
 {
-	bool needs_resize = getShowCounter() != show;
-
-	LLChiclet::setShowCounter(show);
-	mCounterCtrl->setVisible(getShowCounter());
-
-	if(needs_resize)
-	{
-		onChicletSizeChanged();
-	}
+	LLIMChiclet::setOtherParticipantId(other_participant_id);
+	mChicletIconCtrl->setValue(getOtherParticipantId());
 }
 
-
-void LLIMChiclet::setSessionId(const LLUUID& session_id)
+void LLIMP2PChiclet::updateMenuItems()
 {
-	LLChiclet::setSessionId(session_id);
+	if(!mPopupMenu)
+		return;
+	if(getSessionId().isNull())
+		return;
 
-	//for a group chat session_id = group_id
-	LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id);
-	if (!im) return; //should never happen
-	
-	EInstantMessage type = im->getDialogType();
-	if (type == IM_SESSION_INVITE || type == IM_SESSION_GROUP_START)
-	{
-		if (!gAgent.isInGroup(session_id)) return;
+	bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
 
-		if (mGroupInsignia) {
-			LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
-			LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
-			if (group_data && group_data->mInsigniaID.notNull())
-			{
-				mGroupInsignia->setVisible(TRUE);
-				mGroupInsignia->setValue(group_data->mInsigniaID);
-			}
-			else
-			{
-				mID = session_id; //needed for LLGroupMgrObserver
-				grp_mgr->addObserver(this);
-				grp_mgr->sendGroupPropertiesRequest(session_id);
-			}
-		}
-	}	
+	mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
+	mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
 }
 
-void LLIMChiclet::setIMSessionName(const std::string& name)
+BOOL LLIMP2PChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	setToolTip(name);
+	if(!mPopupMenu)
+	{
+		createPopupMenu();
+	}
+
+	if (mPopupMenu)
+	{
+		updateMenuItems();
+		mPopupMenu->arrangeAndClear();
+		LLMenuGL::showPopup(this, mPopupMenu, x, y);
+	}
+
+	return TRUE;
 }
 
-//session id should be set before calling this
-void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
+void LLIMP2PChiclet::createPopupMenu()
 {
-	llassert(getSessionId().notNull());
+	if(mPopupMenu)
+	{
+		llwarns << "Menu already exists" << llendl;
+		return;
+	}
+	if(getSessionId().isNull())
+	{
+		return;
+	}
 
-	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
 
-	//all alive sessions have alive floater, haven't they?
-	llassert(floater);
+	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+		("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+}
 
-	mOtherParticipantId = other_participant_id;
+void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+	std::string level = user_data.asString();
+	LLUUID other_participant_id = getOtherParticipantId();
 
-	if (mAvatarCtrl && floater->getDialogType() == IM_NOTHING_SPECIAL)
+	if("profile" == level)
 	{
-		mAvatarCtrl->setVisible(TRUE);
-		mAvatarCtrl->setValue(other_participant_id);
+		LLAvatarActions::showProfile(other_participant_id);
+	}
+	else if("im" == level)
+	{
+		LLAvatarActions::startIM(other_participant_id);
+	}
+	else if("add" == level)
+	{
+		LLAvatarActions::requestFriendshipDialog(other_participant_id);
 	}
 }
 
-
-void LLIMChiclet::changed(LLGroupChange gc)
+void LLIMP2PChiclet::setShowSpeaker(bool show)
 {
-	LLSD group_insignia = mGroupInsignia->getValue();
-	if (group_insignia.isUUID() && group_insignia.asUUID().notNull()) return;
+	LLIMChiclet::setShowSpeaker(show);
 
-	if (GC_PROPERTIES == gc)
+	bool needs_resize = getShowSpeaker() != show;
+	mSpeakerCtrl->setVisible(getShowSpeaker());
+	if(needs_resize)
 	{
-		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
-		if (group_data && group_data->mInsigniaID.notNull())
-		{
-			mGroupInsignia->setVisible(TRUE);
-			mGroupInsignia->setValue(group_data->mInsigniaID);
-		}
+		onChicletSizeChanged();
 	}
 }
 
-LLUUID LLIMChiclet::getOtherParticipantId()
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLIMGroupChiclet::Params::Params()
+: group_icon("group_icon")
 {
-	return mOtherParticipantId;
+	rect(LLRect(0, 25, 45, 0));
+
+	group_icon.name("group_icon");
+	group_icon.rect(LLRect(0, 25, 25, 0));
+
+	unread_notifications.name("unread");
+	unread_notifications.rect(LLRect(25, 25, 45, 0));
+	unread_notifications.font(LLFontGL::getFontSansSerif());
+	unread_notifications.font_halign(LLFontGL::HCENTER);
+	unread_notifications.v_pad(5);
+	unread_notifications.text_color(LLColor4::white);
+
+	speaker.name("speaker");
+	speaker.rect(LLRect(45, 25, 65, 0));
+
+	show_speaker = false;
 }
 
-void LLIMChiclet::updateMenuItems()
+LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
+: LLIMChiclet(p)
+, LLGroupMgrObserver(LLUUID::null)
+, mChicletIconCtrl(NULL)
+, mCounterCtrl(NULL)
+, mSpeakerCtrl(NULL)
+, mPopupMenu(NULL)
 {
-	if(!mPopupMenu)
-		return;
-	if(getSessionId().isNull())
-		return;
+	LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
+	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params);
+	addChild(mChicletIconCtrl);
 
-	if(P2P_MENU_NAME == mPopupMenu->getName())
-	{
-		bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
+	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+	addChild(mCounterCtrl);
 
-		mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
-		mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
-	}
+	setCounter(getCounter());
+	setShowCounter(getShowCounter());
+
+	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
+	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
+	addChild(mSpeakerCtrl);
+
+	setShowSpeaker(p.show_speaker);
 }
 
-BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+LLIMGroupChiclet::~LLIMGroupChiclet()
 {
-	onMouseDown();
-	return LLChiclet::handleMouseDown(x, y, mask);
+	LLGroupMgr::getInstance()->removeObserver(this);
 }
 
-void LLIMChiclet::setShowSpeaker(bool show)
+void LLIMGroupChiclet::setCounter(S32 counter)
 {
-	bool needs_resize = getShowSpeaker() != show;
-
-	mShowSpeaker = show;
-	mSpeakerCtrl->setVisible(getShowSpeaker());
+	mCounterCtrl->setCounter(counter);
 
-	if(needs_resize)
+	if(getShowCounter())
 	{
-		onChicletSizeChanged();
+		LLRect counter_rect = mCounterCtrl->getRect();
+		LLRect required_rect = mCounterCtrl->getRequiredRect();
+		bool needs_resize = required_rect.getWidth() != counter_rect.getWidth();
+
+		if(needs_resize)
+		{
+			counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth();
+			mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight());
+			mCounterCtrl->setRect(counter_rect);
+
+			onChicletSizeChanged();
+		}
 	}
 }
 
-void LLIMChiclet::draw()
+LLRect LLIMGroupChiclet::getRequiredRect()
 {
-	LLUICtrl::draw();
+	LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
+	if(getShowCounter())
+	{
+		rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
+	}
+	if(getShowSpeaker())
+	{
+		rect.mRight += mSpeakerCtrl->getRect().getWidth();
+	}
+	return rect;
+}
 
-	//if we have a docked floater, we want to position it relative to us
-	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", getSessionId());
+void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
+{
+	LLChiclet::setSessionId(session_id);
 
-	if (im_floater && im_floater->isDocked()) 
+	LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
+	LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
+	if (group_data && group_data->mInsigniaID.notNull())
 	{
-		S32 x, y;
-		getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y);
-		im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom);	
-		//set this so the docked floater knows it's been positioned and can now draw
-		im_floater->setPositioned(true);
+		mChicletIconCtrl->setValue(group_data->mInsigniaID);
 	}
+	else
+	{
+		if(getSessionId() != mID)
+		{
+			grp_mgr->removeObserver(this);
+			mID = getSessionId();
+			grp_mgr->addObserver(this);
+		}
+		grp_mgr->sendGroupPropertiesRequest(session_id);
+	}
+}
 
-	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+void LLIMGroupChiclet::changed(LLGroupChange gc)
+{
+	if (GC_PROPERTIES == gc)
+	{
+		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
+		if (group_data)
+		{
+			mChicletIconCtrl->setValue(group_data->mInsigniaID);
+		}
+	}
 }
 
-BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	if(!mPopupMenu)
+	{
 		createPopupMenu();
-
-	updateMenuItems();
+	}
 
 	if (mPopupMenu)
 	{
 		mPopupMenu->arrangeAndClear();
+		LLMenuGL::showPopup(this, mPopupMenu, x, y);
 	}
-	
-	LLMenuGL::showPopup(this, mPopupMenu, x, y);
 
 	return TRUE;
 }
 
-void LLIMChiclet::createPopupMenu()
+void LLIMGroupChiclet::createPopupMenu()
 {
 	if(mPopupMenu)
 	{
@@ -469,55 +550,41 @@ void LLIMChiclet::createPopupMenu()
 		return;
 	}
 	if(getSessionId().isNull())
+	{
 		return;
-
-	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
-	if(!floater)
-		return;
+	}
 
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2));
+	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
 
-	switch(floater->getDialogType())
-	{
-	case IM_SESSION_GROUP_START:
-		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-			("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-		break;
-	case IM_NOTHING_SPECIAL:
-		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-			("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-		break;
-	default:
-		llwarns << "Unexpected dialog type" << llendl;
-		break;
-	}
+	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+		("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 }
 
-void LLIMChiclet::onMenuItemClicked(const LLSD& user_data)
+void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
 {
 	std::string level = user_data.asString();
-	LLUUID other_participant_id = getOtherParticipantId();
+	LLUUID group_id = getSessionId();
 
-	if("profile" == level)
+	if("group chat" == level)
 	{
-		LLAvatarActions::showProfile(other_participant_id);
+		LLGroupActions::startChat(group_id);
 	}
-	else if("im" == level)
-	{
-		LLAvatarActions::startIM(other_participant_id);
-	}
-	else if("add" == level)
-	{
-		LLAvatarActions::requestFriendshipDialog(other_participant_id);
-	}
-	else if("group chat" == level)
+	else if("info" == level)
 	{
-		LLGroupActions::startChat(other_participant_id);
+		LLGroupActions::show(group_id);
 	}
-	else if("info" == level)
+}
+
+void LLIMGroupChiclet::setShowSpeaker(bool show)
+{
+	LLIMChiclet::setShowSpeaker(show);
+
+	bool needs_resize = getShowSpeaker() != show;
+	mSpeakerCtrl->setVisible(getShowSpeaker());
+	if(needs_resize)
 	{
-		LLGroupActions::show(other_participant_id);
+		onChicletSizeChanged();
 	}
 }
 
@@ -1178,6 +1245,28 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p)
+: LLIconCtrl(p)
+, mDefaultIcon(p.default_icon)
+{
+}
+
+void LLChicletGroupIconCtrl::setValue(const LLSD& value )
+{
+	if(value.asUUID().isNull())
+	{
+		LLIconCtrl::setValue(mDefaultIcon);
+	}
+	else
+	{
+		LLIconCtrl::setValue(value);
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
 LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
  : LLIconCtrl(p)
 {
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index b1e73c9d8d8ccdab9cb616e5db8c1504e0fd84bb..f96dfb69ecbb534471abb1ab61223134d6928649 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -95,7 +95,7 @@ class LLChicletNotificationCounterCtrl : public LLTextBox
 };
 
 /*
- * Class for displaying avatar's icon.
+ * Class for displaying avatar's icon in P2P chiclet.
 */
 class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
 {
@@ -116,6 +116,36 @@ class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
 	friend class LLUICtrlFactory;
 };
 
+/**
+ * Class for displaying group's icon in Group chiclet.
+ */
+class LLChicletGroupIconCtrl : public LLIconCtrl
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLIconCtrl::Params>
+	{
+		Optional<std::string> default_icon;
+
+		Params()
+		 : default_icon("default_icon", "default_land_picture.j2c")
+		{
+		};
+	};
+
+	/**
+	 * Sets icon, if value is LLUUID::null - default icon will be set.
+	 */
+	virtual void setValue(const LLSD& value );
+
+protected:
+
+	LLChicletGroupIconCtrl(const Params& p);
+	friend class LLUICtrlFactory;
+
+	std::string mDefaultIcon;
+};
+
 /*
  * Class for displaying status of Voice Chat 
 */
@@ -231,75 +261,46 @@ class LLChiclet : public LLUICtrl
 	chiclet_size_changed_signal_t mChicletSizeChangedSignal;
 };
 
+
 /*
-* Implements Instant Message chiclet.
-* IMChiclet displays avatar's icon, number of unread messages(optional)
+* Base class for Instant Message chiclets.
+* IMChiclet displays icon, number of unread messages(optional)
 * and voice chat status(optional).
+* Every chiclet should override LLUICtrl::getRequiredRect and return 
+* desired width.
 */
-class LLIMChiclet : public LLChiclet, LLGroupMgrObserver
+class LLIMChiclet : public LLChiclet
 {
 public:
-	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
-	{
-		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
-		Optional<LLIconCtrl::Params> group_insignia;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<bool>	show_speaker;
-
-		Params();
-	};
-
-	/*virtual*/ ~LLIMChiclet();
-
-	virtual void setSessionId(const LLUUID& session_id);
+	
+	/*virtual*/ ~LLIMChiclet() {};
 
 	/*
 	 * Sets IM session name. This name will be displayed in chiclet tooltip.
 	*/
-	virtual void setIMSessionName(const std::string& name);
+	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
 
 	/*
 	 * Sets id of person/group user is chatting with.
 	 * Session id should be set before calling this
 	*/
-	virtual void setOtherParticipantId(const LLUUID& other_participant_id);
+	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
 
 	/*
 	 * Gets id of person/group user is chatting with.
 	 */
-	virtual LLUUID getOtherParticipantId();
+	virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
 
 	/*
 	 * Shows/hides voice chat status control.
 	*/
-	virtual void setShowSpeaker(bool show);
+	virtual void setShowSpeaker(bool show) { mShowSpeaker = show; }
 
 	/*
 	 * Returns voice chat status control visibility.
 	*/
 	virtual bool getShowSpeaker() {return mShowSpeaker;};
 
-	/*
-	 * Sets number of unread messages. Will update chiclet's width if number text 
-	 * exceeds size of counter and notify it's parent about size change.
-	*/
-	/*virtual*/ void setCounter(S32);
-
-	/*
-	 * Returns number of unread messages.
-	*/
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-	/*
-	 * Shows/hides number of unread messages.
-	*/
-	/*virtual*/ void setShowCounter(bool show);
-
 	/*
 	 * Draws border around chiclet.
 	*/
@@ -313,52 +314,13 @@ class LLIMChiclet : public LLChiclet, LLGroupMgrObserver
 	 */
 	void onMouseDown();
 
-	/*
-	 * Returns rect, required to display chiclet.
-	 * Width is the only valid value.
-	*/
-	/*virtual*/ LLRect getRequiredRect();
-
-	/** comes from LLGroupMgrObserver */
-	virtual void changed(LLGroupChange gc);
-
 protected:
 
-	LLIMChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/*
-	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
-	 * based on other participant's id.
-	*/
-	virtual void createPopupMenu();
-
-	/*
-	 * Processes clicks on chiclet popup menu.
-	*/
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/* 
-	 * Enables/disables menus based on relationship with other participant.
-	*/
-	virtual void updateMenuItems();
-
-	/*
-	 * Displays popup menu.
-	*/
-	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+	LLIMChiclet(const LLChiclet::Params& p);
 
 	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 
 protected:
-	LLChicletAvatarIconCtrl* mAvatarCtrl;
-
-	/** the icon of a group in case of group chat */
-	LLIconCtrl* mGroupInsignia;
-	LLChicletNotificationCounterCtrl* mCounterCtrl;
-	LLChicletSpeakerCtrl* mSpeakerCtrl;
-
-	LLMenuGL* mPopupMenu;
 
 	bool mShowSpeaker;
 
@@ -387,6 +349,160 @@ class LLIMChiclet : public LLChiclet, LLGroupMgrObserver
 			sFindChicletsSignal;
 };
 
+/**
+ * Implements P2P chiclet.
+ */
+class LLIMP2PChiclet : public LLIMChiclet
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+	{
+		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
+
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+		Optional<LLChicletSpeakerCtrl::Params> speaker;
+
+		Optional<bool>	show_speaker;
+
+		Params();
+	};
+
+	void setOtherParticipantId(const LLUUID& other_participant_id);
+
+	/*virtual*/ void setShowSpeaker(bool show);
+
+	/*
+	* Sets number of unread messages. Will update chiclet's width if number text 
+	* exceeds size of counter and notify it's parent about size change.
+	*/
+	/*virtual*/ void setCounter(S32);
+
+	/*
+	* Returns number of unread messages.
+	*/
+	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+	/*
+	* Returns rect, required to display chiclet.
+	* Width is the only valid value.
+	*/
+	/*virtual*/ LLRect getRequiredRect();
+
+protected:
+	LLIMP2PChiclet(const Params& p);
+	friend class LLUICtrlFactory;
+
+	/*
+	* Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
+	* based on other participant's id.
+	*/
+	virtual void createPopupMenu();
+
+	/*
+	* Processes clicks on chiclet popup menu.
+	*/
+	virtual void onMenuItemClicked(const LLSD& user_data);
+
+	/*
+	* Displays popup menu.
+	*/
+	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	/* 
+	* Enables/disables menus based on relationship with other participant.
+	*/
+	virtual void updateMenuItems();
+
+private:
+
+	LLChicletAvatarIconCtrl* mChicletIconCtrl;
+	LLChicletNotificationCounterCtrl* mCounterCtrl;
+	LLChicletSpeakerCtrl* mSpeakerCtrl;
+	LLMenuGL* mPopupMenu;
+};
+
+/**
+ * Implements Group chat chiclet.
+ */
+class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+	{
+		Optional<LLChicletGroupIconCtrl::Params> group_icon;
+
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+		Optional<LLChicletSpeakerCtrl::Params> speaker;
+
+		Optional<bool>	show_speaker;
+
+		Params();
+	};
+
+	/**
+	 * Sets session id.
+	 * Session ID for group chat is actually Group ID.
+	 */
+	/*virtual*/ void setSessionId(const LLUUID& session_id);
+
+	/**
+	 * Callback for LLGroupMgrObserver, we get this when group data is available or changed.
+	 * Sets group icon.
+	 */
+	/*virtual*/ void changed(LLGroupChange gc);
+
+	/*virtual*/ void setShowSpeaker(bool show);
+
+	/*
+	* Sets number of unread messages. Will update chiclet's width if number text 
+	* exceeds size of counter and notify it's parent about size change.
+	*/
+	/*virtual*/ void setCounter(S32);
+
+	/*
+	* Returns number of unread messages.
+	*/
+	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+	/*
+	* Returns rect, required to display chiclet.
+	* Width is the only valid value.
+	*/
+	/*virtual*/ LLRect getRequiredRect();
+
+	~LLIMGroupChiclet();
+
+protected:
+	LLIMGroupChiclet(const Params& p);
+	friend class LLUICtrlFactory;
+
+	/*
+	* Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
+	* based on other participant's id.
+	*/
+	virtual void createPopupMenu();
+
+	/*
+	* Processes clicks on chiclet popup menu.
+	*/
+	virtual void onMenuItemClicked(const LLSD& user_data);
+
+	/*
+	* Displays popup menu.
+	*/
+	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+private:
+
+	LLChicletGroupIconCtrl* mChicletIconCtrl;
+	LLChicletNotificationCounterCtrl* mCounterCtrl;
+	LLChicletSpeakerCtrl* mSpeakerCtrl;
+	LLMenuGL* mPopupMenu;
+};
+
 /*
  * Implements notification chiclet. Used to display total amount of unread messages 
  * across all IM sessions, total amount of system notifications.
@@ -421,6 +537,7 @@ class LLNotificationChiclet : public LLChiclet
 	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications + mUreadIMNotifications); }
 	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications + mUreadIMNotifications); }
 	void updateUreadIMNotifications();
+	void setToggleState(BOOL toggled);
 
 protected:
 	LLNotificationChiclet(const Params& p);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 7ad60232c7239f3321b86a1bcca91645caec247c..a7f0a8ff9a6973a2b5d20433926f447398dbbcfa 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -55,6 +55,7 @@
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
 #include "llviewermenu.h"
+#include "lltooldraganddrop.h"
 
 static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
 
@@ -73,6 +74,7 @@ class LLSLURLGetter
 		, mLoaded(false) {}
 
 	void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
+	const LLUUID& getLandmarkId() const { return mLandmarkID; }
 
 	const std::string& getSLURL()
 	{
@@ -130,8 +132,21 @@ class LLFavoriteLandmarkButton : public LLButton
 		msg = mUrlGetter.getSLURL();
 		return TRUE;
 	}
+
+	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask)
+	{
+		LLFavoritesBarCtrl* fb = dynamic_cast<LLFavoritesBarCtrl*>(getParent());
+
+		if (fb)
+		{
+			fb->handleHover(x, y, mask);
+		}
+
+		return LLButton::handleHover(x, y, mask);
+	}
 	
 	void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+	const LLUUID& getLandmarkId() const { return mUrlGetter.getLandmarkId(); }
 
 protected:
 	LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
@@ -141,6 +156,33 @@ class LLFavoriteLandmarkButton : public LLButton
 	LLSLURLGetter mUrlGetter;
 };
 
+class LLFavoritesToggleableMenu : public LLToggleableMenu
+{
+public:
+	virtual BOOL handleHover(S32 x, S32 y, MASK mask)
+	{
+		if (fb)
+		{
+			fb->handleHover(x, y, mask);
+		}
+
+		return LLToggleableMenu::handleHover(x, y, mask);
+	}
+
+	void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; }
+
+protected:
+	LLFavoritesToggleableMenu(const LLToggleableMenu::Params& p):
+		LLToggleableMenu(p)
+	{
+	}
+
+	friend class LLUICtrlFactory;
+
+private:
+	LLFavoritesBarCtrl* fb;
+};
+
 /**
  * This class is needed to override LLMenuItemCallGL default handleToolTip function and
  * show SLURL as button tooltip.
@@ -164,6 +206,18 @@ class LLFavoriteLandmarkMenuItem : public LLMenuItemCallGL
 	
 	void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
 
+	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+	{
+		mMouseDownSignal(this, x, y, mask);
+		return LLMenuItemCallGL::handleMouseDown(x, y, mask);
+	}
+
+	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask)
+	{
+		mMouseUpSignal(this, x, y, mask);
+		return LLMenuItemCallGL::handleMouseUp(x, y, mask);
+	}
+
 protected:
 
 	LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {}
@@ -181,6 +235,14 @@ struct LLFavoritesSort
 	// TODO - made it customizible using gSavedSettings
 	bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
 	{
+		S32 sortField1 = a->getSortField();
+		S32 sortField2 = b->getSortField();
+
+		if (!(sortField1 < 0 && sortField2 < 0))
+		{
+			return sortField2 > sortField1;
+		}
+
 		time_t first_create = a->getCreationDate();
 		time_t second_create = b->getCreationDate();
 		if (first_create == second_create)
@@ -239,29 +301,34 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	case DAD_LANDMARK:
 		{
 			// Copy the item into the favorites folder (if it's not already there).
-			LLInventoryItem *item = (LLInventoryItem *)cargo_data;			
-			LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
-			if (item->getParentUUID() == favorites_id)
+			LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+			// check if we are dragging an existing item from the favorites bar
+			if (item && mDragItemId == item->getUUID())
 			{
-				llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
-				break;
+				*accept = ACCEPT_YES_SINGLE;
+
+				if (drop)
+				{
+					handleExistingFavoriteDragAndDrop(x, y);
+				}
 			}
+			else
+			{
+				LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+				if (item->getParentUUID() == favorites_id)
+				{
+					llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
+					break;
+				}
 
-			*accept = ACCEPT_YES_COPY_SINGLE;
+				*accept = ACCEPT_YES_COPY_SINGLE;
 
-			if (drop)
-			{
-				copy_inventory_item(
-						gAgent.getID(),
-						item->getPermissions().getOwner(),
-						item->getUUID(),
-						favorites_id,
-						std::string(),
-						LLPointer<LLInventoryCallback>(NULL));
-
-				llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+				if (drop)
+				{
+					handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
+				}
 			}
-			
 		}
 		break;
 	default:
@@ -271,6 +338,61 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	return TRUE;
 }
 
+void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
+{
+	LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+	if (dest)
+	{
+		updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId());
+	}
+	else
+	{
+		mItems.push_back(gInventory.getItem(mDragItemId));
+	}
+
+	saveItemsOrder(mItems);
+
+	LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*) mPopupMenuHandle.get();
+
+	if (menu && menu->getVisible())
+	{
+		menu->setVisible(FALSE);
+		showDropDownMenu();
+	}
+
+	mDragItemId = LLUUID::null;
+	getWindow()->setCursor(UI_CURSOR_ARROW);
+}
+
+void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
+{
+	LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+	if (dest)
+	{
+		insertBeforeItem(mItems, dest->getLandmarkId(), item->getUUID());
+	}
+	else
+	{
+		mItems.push_back(gInventory.getItem(item->getUUID()));
+	}
+
+	saveItemsOrder(mItems);
+
+	copy_inventory_item(
+			gAgent.getID(),
+			item->getPermissions().getOwner(),
+			item->getUUID(),
+			favorites_id,
+			std::string(),
+			LLPointer<LLInventoryCallback>(NULL));
+
+	getWindow()->setCursor(UI_CURSOR_ARROW);
+
+	llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+}
+
 //virtual
 void LLFavoritesBarCtrl::changed(U32 mask)
 {
@@ -311,9 +433,9 @@ LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()
 
 void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 {
-	LLInventoryModel::item_array_t items;
+	mItems.clear();
 
-	if (!collectFavoriteItems(items))
+	if (!collectFavoriteItems(mItems))
 	{
 		return;
 	}
@@ -331,7 +453,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 
 	const S32 buttonVGap = 2;
 	
-	S32 count = items.count();
+	S32 count = mItems.count();
 
 	const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad");
 	const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2;
@@ -369,7 +491,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 		S32 i;
 		for (i = 0; i < mFirstDropDownItem; ++i)
 		{
-			if (mItemNamesCache.get(i) != items.get(i)->getName())
+			if (mItemNamesCache.get(i) != mItems.get(i)->getName())
 			{
 				break;
 			}
@@ -387,7 +509,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 		mItemNamesCache.clear();
 		for (S32 i = 0; i < mFirstDropDownItem; i++)
 		{
-			mItemNamesCache.put(items.get(i)->getName());
+			mItemNamesCache.put(mItems.get(i)->getName());
 		}
 
 		// Rebuild the buttons only
@@ -404,7 +526,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 			}
 		}
 
-		createButtons(items, buttonXMLNode, buttonWidth, buttonHGap);
+		createButtons(mItems, buttonXMLNode, buttonWidth, buttonHGap);
 	}
 
 	// Chevron button
@@ -467,9 +589,9 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
 {
 	S32 curr_x = buttonHGap;
 	// Adding buttons
-	for(S32 i = mFirstDropDownItem -1; i >= 0; i--)
+	for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--)
 	{
-		LLInventoryItem* item = items.get(i);
+		LLViewerInventoryItem* item = items.get(j++);
 
 		LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
 		if (NULL == fav_btn)
@@ -488,6 +610,10 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
 		fav_btn->setToolTip(item->getName());
 		fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
 		fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 ));
+
+		fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+		fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+
 		sendChildToBack(fav_btn);
 
 		curr_x += buttonWidth + buttonHGap;
@@ -521,6 +647,15 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 
 	std::sort(items.begin(), items.end(), LLFavoritesSort());
 
+	if (needToSaveItemsOrder(items))
+	{
+		S32 sortField = 0;
+		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+		{
+			(*i)->setSortField(++sortField);
+		}
+	}
+
 	return TRUE;
 }
 
@@ -528,7 +663,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 {
 	if (mPopupMenuHandle.isDead())
 	{
-		LLToggleableMenu::Params menu_p;
+		LLFavoritesToggleableMenu::Params menu_p;
 		menu_p.name("favorites menu");
 		menu_p.can_tear_off(false);
 		menu_p.visible(false);
@@ -536,26 +671,26 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		menu_p.max_scrollable_items = 10;
 		menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
 
-		LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
-
+		LLFavoritesToggleableMenu* menu = LLUICtrlFactory::create<LLFavoritesToggleableMenu>(menu_p);
+		menu->initFavoritesBarPointer(this);
 		mPopupMenuHandle = menu->getHandle();
 	}
 
-	LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
+	LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*)mPopupMenuHandle.get();
 
 	if(menu)
 	{
 		if (!menu->toggleVisibility())
 			return;
 
-		LLInventoryModel::item_array_t items;
+		mItems.clear();
 
-		if (!collectFavoriteItems(items))
+		if (!collectFavoriteItems(mItems))
 		{
 			return;
 		}
 
-		S32 count = items.count();
+		S32 count = mItems.count();
 
 		// Check it there are changed items, since last call
 		if (mItemNamesCache.size() == count)
@@ -563,7 +698,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 			S32 i;
 			for (i = mFirstDropDownItem; i < count; i++)
 			{
-				if (mItemNamesCache.get(i) != items.get(i)->getName())
+				if (mItemNamesCache.get(i) != mItems.get(i)->getName())
 				{
 					break;
 				}
@@ -587,7 +722,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		{
 			for (S32 i = mFirstDropDownItem; i < count; i++)
 			{
-				mItemNamesCache.put(items.get(i)->getName());
+				mItemNamesCache.put(mItems.get(i)->getName());
 			}
 		}
 
@@ -598,17 +733,18 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 
 		for(S32 i = mFirstDropDownItem; i < count; i++)
 		{
-			LLInventoryItem* item = items.get(i);
+			LLViewerInventoryItem* item = mItems.get(i);
 			const std::string& item_name = item->getName();
 
-			LLMenuItemCallGL::Params item_params;
+			LLFavoriteLandmarkMenuItem::Params item_params;
 			item_params.name(item_name);
 			item_params.label(item_name);
 			
 			item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
 			LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
 			menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4));
-			menu_item->setLandmarkID(item->getUUID());
+			menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+			menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
 
 			// Check whether item name wider than menu
 			if (menu_item->getNominalWidth() > max_width)
@@ -644,13 +780,6 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 
 void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
 {
-	LLInventoryModel::item_array_t items;
-
-	if (!collectFavoriteItems(items))
-	{
-		return;
-	}
-
 	// We only have one Inventory, gInventory. Some day this should be better abstracted.
 	LLInvFVBridgeAction::doAction(item_id,&gInventory);
 }
@@ -797,5 +926,135 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
 	}
 }
 
+void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+	mDragItemId = id;
+	mStartDrag = TRUE;
+
+	S32 screenX, screenY;
+	localPointToScreen(x, y, &screenX, &screenY);
+
+	LLToolDragAndDrop::getInstance()->setDragStart(screenX, screenY);
+}
+
+void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+	mDragItemId = LLUUID::null;
+}
+
+BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+	if (mDragItemId != LLUUID::null && mStartDrag)
+	{
+		S32 screenX, screenY;
+		localPointToScreen(x, y, &screenX, &screenY);
+
+		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screenX, screenY))
+		{
+			LLToolDragAndDrop::getInstance()->beginDrag(
+				DAD_LANDMARK, mDragItemId,
+				LLToolDragAndDrop::SOURCE_LIBRARY);
+
+			mStartDrag = FALSE;
+
+			return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
+		}
+	}
+
+	return TRUE;
+}
+
+LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
+{
+	LLUICtrl* ctrl = 0;
+	S32 screenX, screenY;
+	const child_list_t* list = getChildList();
+
+	localPointToScreen(x, y, &screenX, &screenY);
+
+	// look for a child which contains the point (screenX, screenY) in it's rectangle
+	for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
+	{
+		LLRect rect;
+		localRectToScreen((*i)->getRect(), &rect);
+
+		if (rect.pointInRect(screenX, screenY))
+		{
+			ctrl = dynamic_cast<LLUICtrl*>(*i);
+			break;
+		}
+	}
+
+	return ctrl;
+}
+
+BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array_t& items)
+{
+	BOOL result = FALSE;
+
+	// if there is an item without sort order field set, we need to save items order
+	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+	{
+		if ((*i)->getSortField() < 0)
+		{
+			result = TRUE;
+			break;
+		}
+	}
+
+	return result;
+}
+
+void LLFavoritesBarCtrl::saveItemsOrder(LLInventoryModel::item_array_t& items)
+{
+	int sortField = 0;
+
+	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+	{
+		LLViewerInventoryItem* item = *i;
+
+		item->setSortField(++sortField);
+		item->setComplete(TRUE);
+		item->updateServer(FALSE);
+
+		gInventory.updateItem(item);
+	}
+
+	gInventory.notifyObservers();
+}
+
+LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
+{
+	LLInventoryModel::item_array_t::iterator result = items.end();
+
+	for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+	{
+		if ((*i)->getUUID() == id)
+		{
+			result = i;
+			break;
+		}
+	}
+
+	return result;
+}
+
+void LLFavoritesBarCtrl::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId)
+{
+	LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId);
+	LLViewerInventoryItem* destItem = gInventory.getItem(destItemId);
+
+	items.erase(findItemByUUID(items, srcItem->getUUID()));
+	items.insert(findItemByUUID(items, destItem->getUUID()), srcItem);
+}
+
+void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId)
+{
+	LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId);
+	LLViewerInventoryItem* insertedItem = gInventory.getItem(insertedItemId);
+
+	items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem);
+}
 
 // EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 824b396add820037a13595d150bd52a36fc0f0ce..4cd92d1a58be22344252479f0ed3861b7fb81e82 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -60,6 +60,8 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 								   EAcceptance* accept,
 								   std::string& tooltip_msg);
 
+	/*virtual*/ BOOL	handleHover(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);
@@ -73,10 +75,12 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 	void onButtonClick(LLUUID id);
 	void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
 	
+	void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+	void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+
 	void doToSelected(const LLSD& userdata);
 	BOOL isClipboardPasteable() const;
 	void pastFromClipboard() const;
-
 	
 	void showDropDownMenu();
 
@@ -94,8 +98,49 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 	LLRect mChevronRect;
 
 	std::string mChevronButtonToolTip;
+
+private:
+	/*
+	 * Helper function to make code more readable. It handles all drag and drop
+	 * operations of the existing favorites items on the favorites bar.
+	 */
+	void handleExistingFavoriteDragAndDrop(S32 x, S32 y);
+
+	/*
+	 * Helper function to make code more readable. It handles all drag and drop
+	 * operations of the new landmark to the favorites bar.
+	 */
+	void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y);
+
+	// finds a control under the specified LOCAL point
+	LLUICtrl* findChildByLocalCoords(S32 x, S32 y);
+
+	// checks if the current order of the favorites items must be saved
+	BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+	// saves current order of the favorites items
+	void saveItemsOrder(LLInventoryModel::item_array_t& items);
+
+	/*
+	 * changes favorites items order by insertion of the item identified by srcItemId
+	 * BEFORE the item identified by destItemId. both items must exist in items array.
+	 */
+	void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId);
+
+	/*
+	 * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId.
+	 * this function assumes that an item identified by insertedItemId doesn't exist in items array.
+	 */
+	void insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId);
+
+	// finds an item by it's UUID in the items array
+	LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
+
+	BOOL mSkipUpdate;
+	BOOL mStartDrag;
+	LLUUID mDragItemId;
+	LLInventoryModel::item_array_t mItems;
 };
 
 
 #endif // LL_LLFAVORITESBARCTRL_H
-
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 56c5eaa70e1700f6b17a66b616b281acdbac24ca..caa10e945274c9b3d46c252614b5a37241eacd97 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -99,24 +99,20 @@ BOOL LLFloaterAbout::postBuild()
 	LLViewerTextEditor *credits_widget = 
 		getChild<LLViewerTextEditor>("credits_editor", true);
 
-	// For some reason, adding style doesn't work unless this is true.
+	// make sure that we handle hyperlinks in the About text
 	support_widget->setParseHTML(TRUE);
 
-	// Text styles for release notes hyperlinks
-	LLStyle::Params link_style_params;
-	link_style_params.color.control = "HTMLLinkColor";
-	link_style_params.link_href = get_viewer_release_notes_url();
-
 	// Version string
 	std::string version = LLTrans::getString("APP_NAME")
 		+ llformat(" %d.%d.%d (%d) %s %s (%s)\n",
 				   LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,
 				   __DATE__, __TIME__,
 				   gSavedSettings.getString("VersionChannelName").c_str());
-	support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
-	support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, link_style_params);
 
 	std::string support;
+	support.append(version);
+	support.append("[" + get_viewer_release_notes_url() + " " +
+				   LLTrans::getString("ReleaseNotes") + "]");
 	support.append("\n\n");
 
 #if LL_MSVC
@@ -131,10 +127,6 @@ BOOL LLFloaterAbout::postBuild()
 	LLViewerRegion* region = gAgent.getRegion();
 	if (region)
 	{
-		LLStyle::Params server_link_style_params;
-		server_link_style_params.color.control = "HTMLLinkColor";
-		server_link_style_params.link_href = region->getCapability("ServerReleaseNotes");
-
 		const LLVector3d &pos = gAgent.getPositionGlobal();
 		LLUIString pos_text = getString("you_are_at");
 		pos_text.setArg("[POSITION]",
@@ -154,11 +146,9 @@ BOOL LLFloaterAbout::postBuild()
 		support.append(")\n");
 		support.append(gLastVersionChannel);
 		support.append("\n");
-
-		support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
-		support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style_params);
-
-		support = "\n\n";
+		support.append("[" + LLWeb::escapeURL(region->getCapability("ServerReleaseNotes")) +
+					   " " + LLTrans::getString("ReleaseNotes") + "]");
+		support.append("\n\n");
 	}
 
 	// *NOTE: Do not translate text like GPU, Graphics Card, etc -
@@ -248,20 +238,20 @@ BOOL LLFloaterAbout::postBuild()
 }
 
 
- static std::string get_viewer_release_notes_url()
- {
- 	std::ostringstream version;
- 	version << LL_VERSION_MAJOR << "."
- 		<< LL_VERSION_MINOR << "."
- 		<< LL_VERSION_PATCH << "."
- 		<< LL_VERSION_BUILD;
+static std::string get_viewer_release_notes_url()
+{
+	std::ostringstream version;
+	version << LL_VERSION_MAJOR << "."
+		<< LL_VERSION_MINOR << "."
+		<< LL_VERSION_PATCH << "."
+		<< LL_VERSION_BUILD;
 
- 	LLSD query;
- 	query["channel"] = gSavedSettings.getString("VersionChannelName");
- 	query["version"] = version.str();
+	LLSD query;
+	query["channel"] = gSavedSettings.getString("VersionChannelName");
+	query["version"] = version.str();
 
- 	std::ostringstream url;
-	 url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
+	std::ostringstream url;
+	url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
 
- 	return url.str();
- }
+	return LLWeb::escapeURL(url.str());
+}
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 0dee3a1e83630fe793499daa10934e145911e0f5..14fb93df6144c115a79f7cb400d02b189cde4f48 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -47,7 +47,6 @@
 #include "llconsole.h"
 #include "llfloateractivespeakers.h"
 #include "llfloaterchatterbox.h"
-#include "llfloatermute.h"
 #include "llfloaterreg.h"
 #include "llfloaterscriptdebug.h"
 #include "llkeyboard.h"
@@ -56,6 +55,7 @@
 //#include "llresizehandle.h"
 #include "llchatbar.h"
 #include "llrecentpeople.h"
+#include "llpanelblockedlist.h"
 #include "llstatusbar.h"
 #include "llviewertexteditor.h"
 #include "llviewergesture.h"			// for triggering gestures
@@ -280,7 +280,7 @@ void LLFloaterChat::onClickMute(void *data)
 	LLMute mute(id);
 	mute.setFromDisplayName(name);
 	LLMuteList::getInstance()->add(mute);
-	LLFloaterReg::showInstance("mute");
+	LLPanelBlockedList::showPanelAndSelect(mute.mID);
 }
 
 //static
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index eb73bd6d8f44c50057f9f3af87b3a216cf87dfa2..0c77d88efb91d6038f76109c51889563f5425d24 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -194,6 +194,7 @@ BOOL LLPanelFriends::postBuild()
 	mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
 	mFriendsList->setMaximumSelectCallback(boost::bind(&LLPanelFriends::onMaximumSelect));
 	mFriendsList->setCommitOnSelectionChange(TRUE);
+	mFriendsList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
 	childSetCommitCallback("friend_list", onSelectName, this);
 	getChild<LLScrollListCtrl>("friend_list")->setDoubleClickCallback(onClickIM, this);
 
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 7a88612f1ac642f677f11b66620ec8d7256ae5d7..b1f40d9d1d90afb5b2e5688298505a5df81ac453 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -82,7 +82,12 @@ void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
 BOOL LLFloaterGroupPicker::postBuild()
 {
 	LLScrollListCtrl* list_ctrl = getChild<LLScrollListCtrl>("group list");
-	init_group_list(list_ctrl, gAgent.getGroupID(), mPowersMask);
+	if (list_ctrl)
+	{
+		init_group_list(list_ctrl, gAgent.getGroupID(), mPowersMask);
+		list_ctrl->setDoubleClickCallback(onBtnOK, this);
+		list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);
+	}
 	
 	// Remove group "none" from list. Group "none" is added in init_group_list(). 
 	// Some UI elements use group "none", we need to manually delete it here.
@@ -100,8 +105,6 @@ BOOL LLFloaterGroupPicker::postBuild()
 
 	setDefaultBtn("OK");
 
-	getChild<LLScrollListCtrl>("group list")->setDoubleClickCallback(onBtnOK, this);
-
 	childEnable("OK");
 
 	return TRUE;
@@ -183,7 +186,13 @@ BOOL LLPanelGroups::postBuild()
 	childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
 	childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
 
-	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
+	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");
+	if (list)
+	{
+		init_group_list(list, gAgent.getGroupID());
+		list->setDoubleClickCallback(onBtnIM, this);
+		list->setContextMenu(LLScrollListCtrl::MENU_GROUP);
+	}
 
 	childSetAction("Activate", onBtnActivate, this);
 
@@ -199,8 +208,6 @@ BOOL LLPanelGroups::postBuild()
 
 	setDefaultBtn("IM");
 
-	getChild<LLScrollListCtrl>("group list")->setDoubleClickCallback(onBtnIM, this);
-
 	reset();
 
 	return TRUE;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 4cd09faaaff46f5f42482896c0863bd21784c1c6..e5f5e8eedb0a37b987214fe544f709ef326c5bf6 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1061,6 +1061,7 @@ BOOL LLPanelLandObjects::postBuild()
 	mOwnerList->sortByColumnIndex(3, FALSE);
 	childSetCommitCallback("owner list", onCommitList, this);
 	mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this);
+	mOwnerList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
 
 	return TRUE;
 }
@@ -2297,11 +2298,17 @@ BOOL LLPanelLandAccess::postBuild()
 	
 	mListAccess = getChild<LLNameListCtrl>("AccessList");
 	if (mListAccess)
+	{
 		mListAccess->sortByColumnIndex(0, TRUE); // ascending
+		mListAccess->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
+	}
 
 	mListBanned = getChild<LLNameListCtrl>("BannedList");
 	if (mListBanned)
+	{
 		mListBanned->sortByColumnIndex(0, TRUE); // ascending
+		mListBanned->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
+	}
 
 	return TRUE;
 }
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c47c7b073c2bf2ddde25c2e551a836cbae6d85f8..d389cf06ec247f6ad136a892dcdf863148d94282 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -61,6 +61,7 @@
 #include "llnavigationbar.h"
 #include "llpanellogin.h"
 #include "llradiogroup.h"
+#include "llsearchcombobox.h"
 #include "llsky.h"
 #include "llscrolllistctrl.h"
 #include "llscrolllistitem.h"
@@ -214,6 +215,11 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
 		// flag client texture cache for clearing next time the client runs
 		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
 		LLNotifications::instance().add("CacheWillClear");
+
+		LLSearchHistory::getInstance()->clearHistory();
+		LLSearchHistory::getInstance()->save();
+		LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
+		search_ctrl->clearHistory();
 	}
 	
 	return false;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index d05c9cb9a79d8294e4f0e561e0595bf46f59d278..f334344279c8c34a4fd7e5fee3a98f0689f50f1b 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -725,7 +725,7 @@ void LLFloaterTools::onOpen(const LLSD& key)
 		mTab->selectTabByName(panel);
 	}
 	
-	gMenuBarView->setItemVisible("BuildTools", TRUE);
+	//gMenuBarView->setItemVisible("BuildTools", TRUE);
 }
 
 void LLFloaterTools::onClose()
@@ -755,7 +755,7 @@ void LLFloaterTools::onClose()
 	// so manually reset tool to default (pie menu tool)
 	LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
 
-	gMenuBarView->setItemVisible("BuildTools", FALSE);
+	//gMenuBarView->setItemVisible("BuildTools", FALSE);
 }
 
 void click_popup_info(void*)
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index bef5f094e3b6e83d2ad42fee41af476b27578e4b..97b7f3e9ad04675b9886d985c8700cddcef23b59 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -173,6 +173,15 @@ bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCateg
 	return TRUE == gInventory.isObjectDescendentOf(cat->getUUID(), findFriendFolderUUIDImpl());
 }
 
+bool LLFriendCardsManager::isAnyFriendCategory(const LLUUID& catID) const
+{
+	const LLUUID& friendFolderID = findFriendFolderUUIDImpl();
+	if (catID == friendFolderID)
+		return true;
+
+	return TRUE == gInventory.isObjectDescendentOf(catID, friendFolderID);
+}
+
 void LLFriendCardsManager::syncFriendsFolder()
 {
 	//lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent
@@ -305,10 +314,12 @@ void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInve
 	LLInventoryModel::cat_array_t cats;
 	LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
 
-	LLParticularBuddyCollector matchFunctor(avatarID);
 
 	LLViewerInventoryCategory* friendFolder = gInventory.getCategory(friendFolderUUID);
+	if (NULL == friendFolder)
+		return;
 
+	LLParticularBuddyCollector matchFunctor(avatarID);
 	LLInventoryModel::cat_array_t subFolders;
 	subFolders.push_back(friendFolder);
 
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 18a6d0ab694ed43704fef110225b9ff1d1b5ce97..aa391ce2c162fc0e2bfb039093ab94aebc066bbe 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -76,6 +76,11 @@ class LLFriendCardsManager
 	 */
 	bool isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const;
 
+	/**
+	 *	Checks is the specified category is a Friend folder or any its subfolder
+	 */
+	bool isAnyFriendCategory(const LLUUID& catID) const;
+
 	/**
 	 *	Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List
 	 */
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 278fd5b9f6f5487e542de56adcc970d2fa7a0b4a..73d3a60701aa4ed91521f12af357ecd5299db90c 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -51,6 +51,8 @@ LLGroupList::Params::Params()
 LLGroupList::LLGroupList(const Params& p)
 :	LLAvatarList(p)
 {
+	// display a context menu appropriate for a list of group names
+	setContextMenu(LLScrollListCtrl::MENU_GROUP);
 }
 
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9cf3e57e222559cf64bdeb82925b6a3852b86a29..674fff40409323bcbc272fa62af402ed1c7c640b 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -2125,6 +2125,7 @@ BOOL LLIMFloater::postBuild()
 	childSetCommitCallback("chat_editor", onSendMsg, this);
 	
 	mHistoryEditor = getChild<LLViewerTextEditor>("im_text");
+	mHistoryEditor->setParseHTML(TRUE);
 		
 	setTitle(LLIMModel::instance().getName(mSessionID));
 	setDocked(true);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5272bc21653d1f95731da395be17c2d6c3c88a4e..c1a5f210103f88c440ac5c647d115ed67a10179b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1338,7 +1338,10 @@ S32 LLIMMgr::getNumberOfUnreadIM()
 	S32 num = 0;
 	for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it)
 	{
-		num += (*it).second->mNumUnread;
+		if((*it).first != mBeingRemovedSessionID)
+		{
+			num += (*it).second->mNumUnread;
+		}
 	}
 
 	return num;
@@ -1460,6 +1463,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 		clearPendingInvitation(session_id);
 		clearPendingAgentListUpdates(session_id);
 	}
+
+	// for some purposes storing ID of a sessios that is being removed
+	mBeingRemovedSessionID = session_id;
 	notifyObserverSessionRemoved(session_id);
 
 	//if we don't clear session data on removing the session
@@ -1467,6 +1473,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 	//creating chiclets only on session created even, we need to handle chiclets creation
 	//the same way as LLFloaterIMPanels were managed.
 	LLIMModel::getInstance()->clearSession(session_id);
+
+	// now this session is completely removed
+	mBeingRemovedSessionID.setNull();
 }
 
 void LLIMMgr::inviteToSession(
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index ce6f0394ddb572eb50ca67118ea9ddb311230b25..aed3b68471a00a1f676031fe86b10fc16ed514d6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -264,6 +264,9 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	LLSD mPendingInvitations;
 	LLSD mPendingAgentListUpdates;
+	// ID of a session that is being removed: observers are already told
+	// that this session is being removed, but it is still present in the sessions' map
+	LLUUID	mBeingRemovedSessionID;
 };
 
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 789e628b67dd56222899ba55cdca51862403fe69..adc73111e0124d3c80dc172ca713879696af58ac 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2420,8 +2420,14 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 										drop);
 			break;
 		case DAD_CATEGORY:
-			accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
-											drop);
+			if (LLFriendCardsManager::instance().isAnyFriendCategory(mUUID))
+			{
+				accept = FALSE;
+			}
+			else
+			{
+				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop);
+			}
 			break;
 		default:
 			break;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index aadda3fbfdced220fc46be3bd67704496b9f511b..8062da0dfe78eeffc7347463c941532fa3ee8224 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1112,7 +1112,7 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
 			observer->changed(mModifyMask);
 		}
 
-		// safe way to incrament since changed may delete entries! (@!##%@!@&*!)
+		// safe way to increment since changed may delete entries! (@!##%@!@&*!)
 		iter = mObservers.upper_bound(observer); 
 	}
 
diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp
index c83cde9d83baacf05354a6648c91b7f509536cec..d910dbf7185dc54c2acde60f758a03e88f475a0d 100644
--- a/indra/newview/lllocationhistory.cpp
+++ b/indra/newview/lllocationhistory.cpp
@@ -37,59 +37,41 @@
 #include <iomanip> // for std::setw()
 
 #include "llui.h"
-
-const char LLLocationHistory::delimiter = '\t';
+#include "llsd.h"
+#include "llsdserialize.h"
 
 LLLocationHistory::LLLocationHistory() :
 	mFilename("typed_locations.txt")
 {
 }
 
-void LLLocationHistory::addItem(const std::string & item, const std::string & tooltip) {
+void LLLocationHistory::addItem(const LLLocationHistoryItem& item) {
 	static LLUICachedControl<S32> max_items("LocationHistoryMaxSize", 100);
 
 	// check if this item doesn't duplicate any existing one
-	std::vector<std::string>::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
-			boost::bind(&LLLocationHistory::equalByRegionParcel,this,_1,item));
+	location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(),item);
 	if(item_iter != mItems.end()){
-	/*replace duplicate.
-	 * If an item's region and item's parcel are  equal.
-	 */
-		mToolTips.erase(*item_iter);
 		mItems.erase(item_iter);	
-		
 	}
 
 	mItems.push_back(item);
-	mToolTips[item] = tooltip;
-
+	
 	// If the vector size exceeds the maximum, purge the oldest items.
 	if ((S32)mItems.size() > max_items) {
-		for(std::vector<std::string>::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) {
-			mToolTips.erase(*i);
-			mItems.erase(i);
+		for(location_list_t::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) {
+				mItems.erase(i);
 		}
 	}
 }
 
-/**
- * check if the history item is equal.
- * @return  true - if region name and parcel is equal.  
+/*
+ * @brief Try to find item in history. 
+ * If item has been founded, it will be places into end of history.
+ * @return true - item has founded
  */
-bool LLLocationHistory::equalByRegionParcel(const std::string& item, const std::string& newItem){
-
-	
-	S32 itemIndex = item.find('(');
-	S32 newItemIndex = newItem.find('(');
-	
-	std::string region_parcel  = item.substr(0,itemIndex);
-	std::string new_region_parcel  = newItem.substr(0,newItemIndex);
-	
-	return region_parcel == new_region_parcel;
-}
-bool LLLocationHistory::touchItem(const std::string & item) {
+bool LLLocationHistory::touchItem(const LLLocationHistoryItem& item) {
 	bool result = false;
-	std::vector<std::string>::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);
+	location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);
 
 	// the last used item should be the first in the history
 	if (item_iter != mItems.end()) {
@@ -104,13 +86,6 @@ bool LLLocationHistory::touchItem(const std::string & item) {
 void LLLocationHistory::removeItems()
 {
 	mItems.clear();
-	mToolTips.clear();
-}
-
-std::string LLLocationHistory::getToolTip(const std::string & item) const {
-	std::map<std::string, std::string>::const_iterator i = mToolTips.find(item);
-
-	return i != mToolTips.end() ? i->second : "";
 }
 
 bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t& result) const
@@ -123,7 +98,7 @@ bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t&
 
 	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
 	{
-		std::string haystack = *it;
+		std::string haystack = it->getLocation();
 		LLStringUtil::toLower(haystack);
 
 		if (haystack.find(needle) != std::string::npos)
@@ -139,7 +114,7 @@ void LLLocationHistory::dump() const
 	int i = 0;
 	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it, ++i)
 	{
-	    llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << *it << llendl;
+	    llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << it->getLocation() << llendl;
 	}
 }
 
@@ -158,11 +133,7 @@ void LLLocationHistory::save() const
 
 	for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
 	{
-		std::string tooltip =  getToolTip(*it);
-		if(!tooltip.empty())
-		{
-			file << (*it) << delimiter << tooltip << std::endl;
-		}
+		file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl;
 	}
 
 	file.close();
@@ -186,16 +157,17 @@ void LLLocationHistory::load()
 	
 	// add each line in the file to the list
 	std::string line;
-
+	LLPointer<LLSDParser> parser = new LLSDNotationParser();
 	while (std::getline(file, line)) {
-		size_t dp = line.find(delimiter);
-
-		if (dp != std::string::npos) {
-			const std::string reg_name = line.substr(0, dp);
-			const std::string tooltip = line.substr(dp + 1, std::string::npos);
-
-			addItem(reg_name, tooltip);
+		LLSD s_item;
+		std::istringstream iss(line);
+		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+		{
+			llinfos<< "Parsing saved teleport history failed" << llendl;
+			break;
 		}
+
+		mItems.push_back(s_item);
 	}
 
 	file.close();
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
index 060a6b2fe89206315d19aca467ce1013312409c7..5f9976f87a5302b200eced4062b39becd365f4aa 100644
--- a/indra/newview/lllocationhistory.h
+++ b/indra/newview/lllocationhistory.h
@@ -40,21 +40,84 @@
 #include <map>
 #include <boost/function.hpp>
 
+class LLSD;
+
+enum ELocationType {
+	 TYPED_REGION_SURL//region name or surl 
+	,LANDMARK  // name of landmark
+	,TELEPORT_HISTORY 
+	};
+class LLLocationHistoryItem {
+			
+public:
+	LLLocationHistoryItem(){}
+	LLLocationHistoryItem(std::string typed_location, 
+			LLVector3d global_position, std::string tooltip,ELocationType type ):
+		mLocation(typed_location),		
+		mGlobalPos(global_position),
+		mToolTip(tooltip),
+		mType(type)
+	{}
+	LLLocationHistoryItem(const LLLocationHistoryItem& item):
+		mGlobalPos(item.mGlobalPos),
+		mToolTip(item.mToolTip),
+		mLocation(item.mLocation),
+		mType(item.mType)
+	{}
+	LLLocationHistoryItem(const LLSD& data):
+	mLocation(data["location"]),
+	mGlobalPos(data["global_pos"]),
+	mToolTip(data["tooltip"]),
+	mType(ELocationType(data["item_type"].asInteger()))
+	{}
+
+	bool operator==(const LLLocationHistoryItem& item)
+	{
+		// do not compare  mGlobalPos, 
+		// because of a rounding off , the history  can contain duplicates
+		return mLocation == item.mLocation && (mType == item.mType); 
+	}
+	bool operator!=(const LLLocationHistoryItem& item)
+	{
+		return ! (*this == item);
+	}
+	LLSD toLLSD() const
+	{
+		LLSD val;
+		val["location"]= mLocation;
+		val["global_pos"]	= mGlobalPos.getValue();
+		val["tooltip"]	= mToolTip;
+		val["item_type"] = mType;
+		return val;
+	}
+	const std::string& getLocation() const { return mLocation;	};
+	const std::string& getToolTip() const { return mToolTip;	};
+	//static bool equalByRegionParcel(const LLLocationHistoryItem& item1, const LLLocationHistoryItem& item2);
+	static bool equalByLocation(const LLLocationHistoryItem& item1, const std::string& item_location)
+	{
+		return  item1.getLocation() == item_location;
+	}
+	
+	LLVector3d	mGlobalPos; // global position
+	std::string mToolTip;// SURL
+	std::string mLocation;// typed_location
+	ELocationType mType;
+};
+
 class LLLocationHistory: public LLSingleton<LLLocationHistory>
 {
 	LOG_CLASS(LLLocationHistory);
 
 public:
-	typedef std::vector<std::string>	location_list_t;
+	typedef std::vector<LLLocationHistoryItem>	location_list_t;
 	typedef boost::function<void()>		loaded_callback_t;
 	typedef boost::signals2::signal<void()> loaded_signal_t;
 	
 	LLLocationHistory();
 	
-	void					addItem(const std::string & item, const std::string & tooltip);
-	bool					touchItem(const std::string & item);
+	void					addItem(const LLLocationHistoryItem& item);
+	bool					touchItem(const LLLocationHistoryItem& item);
 	void                    removeItems();
-	std::string				getToolTip(const std::string & item) const;
 	size_t					getItemCount() const	{ return mItems.size(); }
 	const location_list_t&	getItems() const		{ return mItems; }
 	bool					getMatchingItems(std::string substring, location_list_t& result) const;
@@ -65,10 +128,8 @@ class LLLocationHistory: public LLSingleton<LLLocationHistory>
 	void					dump() const;
 
 private:
-	bool equalByRegionParcel(const std::string& item, const  std::string& item_to_add);
-	const static char delimiter;
-	std::vector<std::string>			mItems;
-	std::map<std::string, std::string>	mToolTips;
+
+	location_list_t			mItems;
 	std::string							mFilename; /// File to store the history to.
 	loaded_signal_t						mLoadedSignal;
 };
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index a8ec826e885e1f64bcb09bb1444ba044f1d58d77..f54a614f6254e6da7d23faa9931b133eb30c6062 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -48,6 +48,7 @@
 #include "lllandmarkactions.h"
 #include "lllandmarklist.h"
 #include "lllocationhistory.h"
+#include "llteleporthistory.h"
 #include "llsidetray.h"
 #include "llslurl.h"
 #include "lltrans.h"
@@ -295,11 +296,19 @@ BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect*
 	if (LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen) && !msg.empty())
 	{
 		if (mList->getRect().pointInRect(x, y)) {
-			LLLocationHistory* lh = LLLocationHistory::getInstance();
-			const std::string tooltip = lh->getToolTip(msg);
-
-			if (!tooltip.empty()) {
-				msg = tooltip;
+			S32 loc_x, loc_y;
+			//x,y - contain coordinates related to the location input control, but without taking the expanded list into account
+			//So we have to convert it again into local coordinates of mList
+			localPointToOtherView(x,y,&loc_x,&loc_y,mList);
+			
+			LLScrollListItem* item =  mList->hitItem(loc_x,loc_y);
+			if (item)
+			{
+				LLSD value = item->getValue();
+				if (value.has("tooltip"))
+				{
+					msg = value["tooltip"].asString();
+				}
 			}
 		}
 
@@ -448,18 +457,58 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
 	rebuildLocationHistory(filter);
 
 	//Let's add landmarks to the top of the list if any
-	if( filter.size() !=0 )
+	if(!filter.empty() )
 	{
 		LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, TRUE);
 
 		for(U32 i=0; i < landmark_items.size(); i++)
 		{
-			mList->addSimpleElement(landmark_items[i]->getName(), ADD_TOP);
+			LLSD value;
+			//TODO:: DO we need tooltip for Landmark??
+			
+			value["item_type"] = LANDMARK;
+			value["AssetUUID"] =  landmark_items[i]->getAssetUUID(); 
+			add(landmark_items[i]->getName(), value);
+			
+		}
+	//Let's add teleport history items
+		LLTeleportHistory* th = LLTeleportHistory::getInstance();
+		LLTeleportHistory::slurl_list_t th_items = th->getItems();
+
+		std::set<std::string> new_item_titles;// duplicate control
+		LLTeleportHistory::slurl_list_t::iterator result = std::find_if(
+				th_items.begin(), th_items.end(), boost::bind(
+						&LLLocationInputCtrl::findTeleportItemsByTitle, this,
+						_1, filter));
+
+		while (result != th_items.end())
+		{
+			//mTitile format - region_name[, parcel_name]
+			//mFullTitile format - region_name[, parcel_name] (local_x,local_y, local_z)
+			if (new_item_titles.insert(result->mFullTitle).second)
+			{
+				LLSD value;
+				value["item_type"] = TELEPORT_HISTORY;
+				value["global_pos"] = result->mGlobalPos.getValue();
+				std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
+				//TODO*: add Surl to teleportitem or parse region name from title
+				value["tooltip"] = LLSLURL::buildSLURLfromPosGlobal(region_name,
+						result->mGlobalPos,	false);
+				add(result->getTitle(), value); 
+			}
+			result = std::find_if(result + 1, th_items.end(), boost::bind(
+									&LLLocationInputCtrl::findTeleportItemsByTitle, this,
+									_1, filter));
 		}
 	}
+	sortByName();
+	
 	mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
 }
-
+bool LLLocationInputCtrl::findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter)
+{
+	return item.mTitle.find(filter) != std::string::npos;
+}
 void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)
 {
 	if (mLocationContextMenu)
@@ -519,7 +568,12 @@ void LLLocationInputCtrl::rebuildLocationHistory(std::string filter)
 	removeall();
 	for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
 	{
-		add(*it);
+		LLSD value;
+		value["tooltip"] = it->getToolTip();
+		//location history can contain only typed locations
+		value["item_type"] = TYPED_REGION_SURL;
+		value["global_pos"] = it->mGlobalPos.getValue();
+		add(it->getLocation(), value);
 	}
 }
 
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index d967df8257f308ac57f4f15e22b90d6d683a968d..3c43e1a321913281fe1dfca0c98448b9be07a693 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -41,6 +41,7 @@ class LLLandmark;
 class LLAddLandmarkObserver;
 class LLRemoveLandmarkObserver;
 class LLMenuGL;
+class LLTeleportHistoryItem;
 
 /**
  * Location input control.
@@ -103,6 +104,7 @@ class LLLocationInputCtrl
 	void					refresh();
 	void					refreshLocation();
 	void					rebuildLocationHistory(std::string filter = "");
+	bool 					findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter);
 	void					setText(const LLStringExplicit& text);
 	void					updateAddLandmarkButton();
 	void 					updateContextMenu();
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 1b82c2dc18d5dc9251cf1d80fa6af1cfda68d0aa..8ef6b25c509cf7d3570c456219e9d97d4eb966f0 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -61,9 +61,9 @@ LLNameListCtrl::Params::Params()
 
 LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
 :	LLScrollListCtrl(p),
-	mAllowCallingCardDrop(p.allow_calling_card_drop),
+	mNameColumnIndex(p.name_column.column_index),
 	mNameColumn(p.name_column.column_name),
-	mNameColumnIndex(p.name_column.column_index)
+	mAllowCallingCardDrop(p.allow_calling_card_drop)
 {}
 
 // public
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index e40568a0cb757dcb085c2541f968368a17cfea05..c283b3a05f192b87e7f6246c221a50d2bcea0f2a 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -45,7 +45,7 @@
 #include "lllocationhistory.h"
 #include "lllocationinputctrl.h"
 #include "llteleporthistory.h"
-#include "llsearcheditor.h"
+#include "llsearchcombobox.h"
 #include "llsidetray.h"
 #include "llslurl.h"
 #include "llurlsimstring.h"
@@ -82,7 +82,6 @@ class LLTeleportHistoryMenuItem : public LLMenuItemCallGL
 		Mandatory<EType> item_type;
 
 		Params() {}
-		Params(EType type, std::string title);
 	};
 
 	/*virtual*/ void	draw();
@@ -104,24 +103,21 @@ class LLTeleportHistoryMenuItem : public LLMenuItemCallGL
 const std::string LLTeleportHistoryMenuItem::ICON_IMG_BACKWARD("teleport_history_backward.tga");
 const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_forward.tga");
 
-LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title)
-{
-	item_type(type);
-	font.name("SANSSERIF");
-
-	if (type == TYPE_CURRENT)
-		font.style("BOLD");
-	else
-		title = "   " + title;
-
-	name(title);
-	label(title);
-}
-
 LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
 :	LLMenuItemCallGL(p),
 	mArrowIcon(NULL)
 {
+	// Set appearance depending on the item type.
+	if (p.item_type  == TYPE_CURRENT)
+	{
+		setFont(LLFontGL::getFontSansSerifBold());
+	}
+	else
+	{
+		setFont(LLFontGL::getFontSansSerif());
+		setLabel(std::string("   ") + std::string(p.label));
+	}
+
 	LLIconCtrl::Params icon_params;
 	icon_params.name("icon");
 	icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0));
@@ -183,14 +179,11 @@ LLNavigationBar::LLNavigationBar()
 	mBtnForward(NULL),
 	mBtnHome(NULL),
 	mCmbLocation(NULL),
-	mLeSearch(NULL),
+	mSearchComboBox(NULL),
 	mPurgeTPHistoryItems(false)
 {
 	setIsChrome(TRUE);
 	
-	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(
-			boost::bind(&LLNavigationBar::onTeleportFinished, this, _1));
-
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml");
 
 	// set a listener function for LoginComplete event
@@ -202,8 +195,10 @@ LLNavigationBar::LLNavigationBar()
 
 LLNavigationBar::~LLNavigationBar()
 {
-	mParcelMgrConnection.disconnect();
+	mTeleportFinishConnection.disconnect();
 	sInstance = 0;
+
+	LLSearchHistory::getInstance()->save();
 }
 
 BOOL LLNavigationBar::postBuild()
@@ -213,10 +208,12 @@ BOOL LLNavigationBar::postBuild()
 	mBtnHome	= getChild<LLButton>("home_btn");
 	
 	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); 
-	mLeSearch	= getChild<LLSearchEditor>("search_input");
+	mSearchComboBox	= getChild<LLSearchComboBox>("search_combo_box");
+
+	fillSearchComboBox();
 
 	if (!mBtnBack || !mBtnForward || !mBtnHome ||
-		!mCmbLocation || !mLeSearch)
+		!mCmbLocation || !mSearchComboBox)
 	{
 		llwarns << "Malformed navigation bar" << llendl;
 		return FALSE;
@@ -234,7 +231,7 @@ BOOL LLNavigationBar::postBuild()
 
 	mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
 	
-	mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
+	mSearchComboBox->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
 
 	mDefaultNbRect = getRect();
 	mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect();
@@ -246,6 +243,25 @@ BOOL LLNavigationBar::postBuild()
 	return TRUE;
 }
 
+void LLNavigationBar::fillSearchComboBox()
+{
+	if(!mSearchComboBox)
+	{
+		return;
+	}
+
+	LLSearchHistory::getInstance()->load();
+
+	LLSearchHistory::search_history_list_t search_list = 
+		LLSearchHistory::getInstance()->getSearchHistoryList();
+	LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin();
+	for( ; search_list.end() != it; ++it)
+	{
+		LLSearchHistory::LLSearchHistoryItem item = *it;
+		mSearchComboBox->add(item.search_query);
+	}
+}
+
 void LLNavigationBar::draw()
 {
 	if(mPurgeTPHistoryItems)
@@ -280,7 +296,12 @@ void LLNavigationBar::onHomeButtonClicked()
 
 void LLNavigationBar::onSearchCommit()
 {
-	invokeSearch(mLeSearch->getValue().asString());
+	std::string search_query = mSearchComboBox->getValue().asString();
+	if(!search_query.empty())
+	{
+		LLSearchHistory::getInstance()->addEntry(search_query);
+		invokeSearch(mSearchComboBox->getValue().asString());	
+	}
 }
 
 void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
@@ -299,69 +320,107 @@ void LLNavigationBar::onLocationSelection()
 	if (typed_location.empty())
 		return;
 
+	LLSD value = mCmbLocation->getSelectedValue();
+	
+	if(value.has("item_type"))
+	{
+
+		switch(value["item_type"].asInteger())
+		{
+		case LANDMARK:
+			
+			if(value.has("AssetUUID"))
+			{
+				
+				gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
+				return;
+			}
+			else
+			{
+				LLInventoryModel::item_array_t landmark_items =
+						LLLandmarkActions::fetchLandmarksByName(typed_location,
+								FALSE);
+				if (!landmark_items.empty())
+				{
+					gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID());
+					return; 
+				}
+			}
+			break;
+			
+		case TELEPORT_HISTORY:
+			//in case of teleport item was selected, teleport by position too.
+		case TYPED_REGION_SURL:
+			if(value.has("global_pos"))
+			{
+				gAgent.teleportViaLocation(LLVector3d(value["global_pos"]));
+				return;
+			}
+			break;
+			
+		default:
+			break;		
+		}
+	}
+	//Let's parse surl or region name
+	
 	std::string region_name;
 	LLVector3 local_coords(128, 128, 0);
 	S32 x = 0, y = 0, z = 0;
-
 	// Is the typed location a SLURL?
 	if (LLSLURL::isSLURL(typed_location))
 	{
 		// Yes. Extract region name and local coordinates from it.
 		if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
-			local_coords.set(x, y, z);
+				local_coords.set(x, y, z);
 		else
 			return;
-	}
-	else
+	}else
 	{
-		//If it is not slurl let's look for landmarks
-		LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(typed_location, FALSE);
-		if ( !landmark_items.empty() )
-		{
-			gAgent.teleportViaLandmark(landmark_items[0]->getAssetUUID());
-			return;
-		}
-		//No landmark match, check if it is a region name
-		region_name = parseLocation(typed_location, &x, &y, &z);
-		if (region_name != typed_location)
-			local_coords.set(x, y, z);
-
-		// Treat it as region name.
-		// region_name = typed_location;
+		// assume that an user has typed the {region name} or possible {region_name, parcel}
+		region_name  = typed_location.substr(0,typed_location.find(','));
 	}
-
+	
 	// Resolve the region name to its global coordinates.
 	// If resolution succeeds we'll teleport.
 	LLWorldMap::url_callback_t cb = boost::bind(
 			&LLNavigationBar::onRegionNameResponse, this,
 			typed_location, region_name, local_coords, _1, _2, _3, _4);
+	// connect the callback each time, when user enter new location to get real location of agent after teleport
+	mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
+			setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1,typed_location));
+	
 	LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
 }
 
-void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
+void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location)
 {
 	// Location is valid. Add it to the typed locations history.
 	LLLocationHistory* lh = LLLocationHistory::getInstance();
 
+	//TODO*: do we need convert surl into readable format?
 	std::string location;
 	/*NOTE:
 	 * We can't use gAgent.getPositionAgent() in case of local teleport to build location.
 	 * At this moment gAgent.getPositionAgent() contains previous coordinates.
 	 * according to EXT-65 agent position is being reseted on each frame.  
 	 */
-	LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM,
-			gAgent.getPosAgentFromGlobal(global_agent_pos));
+		LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM,
+					gAgent.getPosAgentFromGlobal(global_agent_pos));
+	std::string tooltip (LLSLURL::buildSLURLfromPosGlobal(gAgent.getRegion()->getName(), global_agent_pos, false));
 	
+	LLLocationHistoryItem item (location,
+			global_agent_pos, tooltip,TYPED_REGION_SURL);// we can add into history only TYPED location
 	//Touch it, if it is at list already, add new location otherwise
-	if ( !lh->touchItem(location) ) {
-		std::string tooltip = LLSLURL::buildSLURLfromPosGlobal(
-				gAgent.getRegion()->getName(), global_agent_pos, false);
-		
-		lh->addItem(location, tooltip);
+	if ( !lh->touchItem(item) ) {
+		lh->addItem(item);
 	}
-	llinfos << "Saving after on teleport finish" << llendl;
-	lh->save();
 
+	lh->save();
+	
+	if(mTeleportFinishConnection.connected())
+		mTeleportFinishConnection.disconnect();
+	
 }
 
 void LLNavigationBar::onTeleportHistoryChanged()
@@ -411,9 +470,13 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()
 		else
 			type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
 
-		LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle());
+		LLTeleportHistoryMenuItem::Params item_params;
+		item_params.label = item_params.name = hist_items[i].getTitle();
+		item_params.item_type = type;
 		item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
-		mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params));
+		LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params);
+		//new_itemp->setFont()
+		mTeleportHistoryMenu->addChild(new_itemp);
 	}
 }
 
@@ -433,8 +496,8 @@ void LLNavigationBar::onRegionNameResponse(
 	// Teleport to the location.
 	LLVector3d region_pos = from_region_handle(region_handle);
 	LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
-	
-	llinfos << "Teleporting to: " << global_pos  << llendl;
+
+	llinfos << "Teleporting to: " << LLSLURL::buildSLURLfromPosGlobal(region_name,	global_pos, false)  << llendl;
 	gAgent.teleportViaLocation(global_pos);
 }
 
@@ -472,35 +535,6 @@ void LLNavigationBar::invokeSearch(std::string search_text)
 	LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));
 }
 
-std::string LLNavigationBar::parseLocation(const std::string & location, S32* x, S32* y, S32* z) {
-	/*
-	 * This regular expression extracts numbers from the following string
-	 * construct: "(num1, num2, num3)", where num1, num2 and num3 are decimal
-	 * numbers. Leading and trailing spaces are also caught by the expression.
-	 */
-	const boost::regex re("\\s*\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)\\s*");
-
-	boost::smatch m;
-	if (boost::regex_search(location, m, re)) {
-		// string representations of parsed by regex++ numbers
-		std::string xstr(m[1].first, m[1].second);
-		std::string ystr(m[2].first, m[2].second);
-		std::string zstr(m[3].first, m[3].second);
-
-		*x = atoi(xstr.c_str());
-		*y = atoi(ystr.c_str());
-		*z = atoi(zstr.c_str());
-		//erase commas in coordinates
-		std::string region_parcel = boost::regex_replace(location, re, "");
-		// cut region name
-		return region_parcel.substr(0, region_parcel.find_first_of(','));
-	}
-
-	*x = *y = *z = 0;
-
-	return location;
-}
-
 void LLNavigationBar::clearHistoryCache()
 {
 	mCmbLocation->removeall();
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 69328478546a8d82f2fe820d5aeb19ad3e387835..8a65cd24face5adadc6dc55bef5f1c86d639e3f4 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -41,6 +41,7 @@ class LLButton;
 class LLLocationInputCtrl;
 class LLMenuGL;
 class LLSearchEditor;
+class LLSearchComboBox;
 
 /**
  * Web browser-like navigation bar.
@@ -69,12 +70,6 @@ class LLNavigationBar
 	void rebuildTeleportHistoryMenu();
 	void showTeleportHistoryMenu();
 	void invokeSearch(std::string search_text);
-
-	/**
-	 * Get region name and local coordinates from typed location
-	 */
-	static std::string parseLocation(const std::string & location, S32* x, S32* y, S32* z);
-
 	// callbacks
 	void onTeleportHistoryMenuItemClicked(const LLSD& userdata);
 	void onTeleportHistoryChanged();
@@ -86,7 +81,7 @@ class LLNavigationBar
 	void onLocationSelection();
 	void onLocationPrearrange(const LLSD& data);
 	void onSearchCommit();
-	void onTeleportFinished(const LLVector3d& global_agent_pos);
+	void onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location);
 	void onRegionNameResponse(
 			std::string typed_location,
 			std::string region_name,
@@ -94,17 +89,19 @@ class LLNavigationBar
 			U64 region_handle, const std::string& url,
 			const LLUUID& snapshot_id, bool teleport);
 
+	void fillSearchComboBox();
+
 	static LLNavigationBar *sInstance;
 	
 	LLMenuGL*					mTeleportHistoryMenu;
 	LLButton*					mBtnBack;
 	LLButton*					mBtnForward;
 	LLButton*					mBtnHome;
-	LLSearchEditor*				mLeSearch;
+	LLSearchComboBox*			mSearchComboBox;
 	LLLocationInputCtrl*		mCmbLocation;
 	LLRect						mDefaultNbRect;
 	LLRect						mDefaultFpRect;
-	boost::signals2::connection	mParcelMgrConnection;
+	boost::signals2::connection	mTeleportFinishConnection;
 	bool						mPurgeTPHistoryItems;
 };
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 3856a86da0c3557bfe1a88573dd960b3d6d657d1..6150d5da3760d1a7adba7ef5a51ba85448af8592 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -183,9 +183,13 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
 
 void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
 {
-	std::string line = chat.mFromName;
-	line +=": ";
-	line +=chat.mText;
+	std::string line = chat.mText;
+
+	//chat.mText starts with Avatar Name if entered message was "/me <action>". 
+	// In this case output chat message should be "<Avatar Name> <action>". See EXT-656
+	// See also process_chat_from_simulator() in the llviewermessage.cpp where ircstyle = TRUE;
+	if (CHAT_STYLE_IRC != chat.mChatStyle)
+		line = chat.mFromName + ": " + line;
 
 	bool prepend_newline = true;
 	if (gSavedSettings.getBOOL("ChatShowTimestamps"))
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 6e94b087a64417f7b3aebe82de95707ee28f8ea4..fd3519bf4b830b00406f48168aac172872c8ec11 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -372,7 +372,6 @@ void LLPanelAvatarProfile::resetControls()
 	childSetVisible("status_me_panel", false);
 	childSetVisible("profile_me_buttons_panel", false);
 	childSetVisible("account_actions_panel", false);
-	childSetVisible("partner_edit_link", false);
 }
 
 void LLPanelAvatarProfile::resetData()
@@ -539,7 +538,7 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
 	childSetValue("acc_status_text", caption_text);
 }
 
-void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url)
+void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)
 {
 	LLWeb::loadURL(url);
 }
@@ -595,9 +594,8 @@ BOOL LLPanelAvatarMeProfile::postBuild()
 
 	childSetCommitCallback("status_combo", boost::bind(&LLPanelAvatarMeProfile::onStatusChanged, this), NULL);
 	childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelAvatarMeProfile::onStatusMessageChanged, this), NULL);
-	childSetActionTextbox("payment_update_link", boost::bind(&LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked, this));
-	childSetActionTextbox("my_account_link", boost::bind(&LLPanelAvatarMeProfile::onMyAccountTextboxClicked, this));
-	childSetActionTextbox("partner_edit_link", boost::bind(&LLPanelAvatarMeProfile::onPartnerEditTextboxClicked, this));
+
+	childSetTextArg("partner_edit_link", "[URL]", getString("partner_edit_link_url"));
 
 	resetControls();
 	resetData();
@@ -676,18 +674,3 @@ void LLPanelAvatarMeProfile::onStatusMessageChanged()
 {
 	updateData();
 }
-
-void LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked()
-{
-	onUrlTextboxClicked(getString("payment_update_link_url"));
-}
-
-void LLPanelAvatarMeProfile::onMyAccountTextboxClicked()
-{
-	onUrlTextboxClicked(getString("my_account_link_url"));
-}
-
-void LLPanelAvatarMeProfile::onPartnerEditTextboxClicked()
-{
-	onUrlTextboxClicked(getString("partner_edit_link_url"));
-}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 51bd619901bac0b448ffcfca236ed05e911a36f4..1ed5fa4357b2af4ed4033d6b37da2fadc5d593fc 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -166,7 +166,7 @@ class LLPanelAvatarProfile
 	 */
 	virtual void fillAccountStatus(const LLAvatarData* avatar_data);
 
-	void onUrlTextboxClicked(std::string url);
+	void onUrlTextboxClicked(const std::string& url);
 	void onHomepageTextboxClicked();
 	void onAddFriendButtonClick();
 	void onIMButtonClick();
@@ -203,9 +203,6 @@ class LLPanelAvatarMeProfile
 
 	void onStatusChanged();
 	void onStatusMessageChanged();
-	void onUpdateAccountTextboxClicked();
-	void onMyAccountTextboxClicked();
-	void onPartnerEditTextboxClicked();
 
 private:
 
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60d0f072855cec248291f235967ea89255769d5d
--- /dev/null
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -0,0 +1,279 @@
+/** 
+ * @file llpanelblockedlist.cpp
+ * @brief Container for blocked Residents & Objects list
+ *
+ * $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 "llviewerprecompiledheaders.h"
+
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "llscrolllistctrl.h"
+
+#include "llpanelblockedlist.h"
+
+// project include
+#include "llfloateravatarpicker.h"
+#include "llsidetray.h"
+#include "llsidetraypanelcontainer.h"
+
+static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
+
+//
+// Constants
+//
+const std::string BLOCKED_PARAM_NAME = "blocked_to_select";
+
+//-----------------------------------------------------------------------------
+// LLPanelBlockedList()
+//-----------------------------------------------------------------------------
+
+LLPanelBlockedList::LLPanelBlockedList()
+:	LLPanel()
+{
+	mCommitCallbackRegistrar.add("Block.ClickPick",			boost::bind(&LLPanelBlockedList::onPickBtnClick, this));
+	mCommitCallbackRegistrar.add("Block.ClickBlockByName",	boost::bind(&LLPanelBlockedList::onBlockByNameClick, this));
+	mCommitCallbackRegistrar.add("Block.ClickRemove",		boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this));
+}
+
+LLPanelBlockedList::~LLPanelBlockedList()
+{
+	LLMuteList::getInstance()->removeObserver(this);
+}
+
+BOOL LLPanelBlockedList::postBuild()
+{
+	mBlockedList = getChild<LLScrollListCtrl>("blocked");
+	mBlockedList->setCommitOnSelectionChange(TRUE);
+
+	childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
+
+	LLMuteList::getInstance()->addObserver(this);
+	
+	refreshBlockedList();
+
+	return LLPanel::postBuild();
+}
+
+void LLPanelBlockedList::draw()
+{
+	updateButtons();
+	LLPanel::draw();
+}
+
+void LLPanelBlockedList::onOpen(const LLSD& key)
+{
+	if (key.has(BLOCKED_PARAM_NAME) && key[BLOCKED_PARAM_NAME].asUUID().notNull())
+	{
+		selectBlocked(key[BLOCKED_PARAM_NAME].asUUID());
+	}
+}
+
+void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
+{
+	mBlockedList->selectByID(mute_id);
+}
+
+void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
+{
+	LLSideTray::getInstance()->showPanel("panel_block_list_sidetray", LLSD().insert(BLOCKED_PARAM_NAME, idToSelect));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+//////////////////////////////////////////////////////////////////////////
+void LLPanelBlockedList::refreshBlockedList()
+{
+	mBlockedList->deleteAllItems();
+
+	std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
+	std::vector<LLMute>::iterator it;
+	for (it = mutes.begin(); it != mutes.end(); ++it)
+	{
+		std::string display_name = it->getDisplayName();
+		mBlockedList->addStringUUIDItem(display_name, it->mID, ADD_BOTTOM, TRUE);
+	}
+}
+
+void LLPanelBlockedList::updateButtons()
+{
+	bool hasSelected = NULL != mBlockedList->getFirstSelected();
+	childSetEnabled("Unblock", hasSelected);
+}
+
+
+
+void LLPanelBlockedList::onBackBtnClick()
+{
+	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+	if(parent)
+	{
+		parent->openPreviousPanel();
+	}
+}
+
+void LLPanelBlockedList::onRemoveBtnClick()
+{
+	std::string name = mBlockedList->getSelectedItemLabel();
+	LLUUID id = mBlockedList->getStringUUIDSelectedItem();
+	LLMute mute(id);
+	mute.setFromDisplayName(name);
+	// now mute.mName has the suffix trimmed off
+	
+	S32 last_selected = mBlockedList->getFirstSelectedIndex();
+	if (LLMuteList::getInstance()->remove(mute))
+	{
+		// Above removals may rebuild this dialog.
+		
+		if (last_selected == mBlockedList->getItemCount())
+		{
+			// we were on the last item, so select the last item again
+			mBlockedList->selectNthItem(last_selected - 1);
+		}
+		else
+		{
+			// else select the item after the last item previously selected
+			mBlockedList->selectNthItem(last_selected);
+		}
+	}
+}
+
+void LLPanelBlockedList::onPickBtnClick()
+{
+	const BOOL allow_multiple = FALSE;
+	const BOOL close_on_select = TRUE;
+	/*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(callbackBlockPicked, this, allow_multiple, close_on_select);
+
+	// *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed?
+	// old Floater dependency is not enable in panel
+	// addDependentFloater(picker);
+}
+
+void LLPanelBlockedList::onBlockByNameClick()
+{
+	LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName);
+}
+
+//static
+void LLPanelBlockedList::callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data)
+{
+	if (names.empty() || ids.empty()) return;
+	LLMute mute(ids[0], names[0], LLMute::AGENT);
+	LLMuteList::getInstance()->add(mute);
+	showPanelAndSelect(mute.mID);
+}
+
+//static
+void LLPanelBlockedList::callbackBlockByName(const std::string& text)
+{
+	if (text.empty()) return;
+
+	LLMute mute(LLUUID::null, text, LLMute::BY_NAME);
+	BOOL success = LLMuteList::getInstance()->add(mute);
+	if (!success)
+	{
+		LLNotifications::instance().add("MuteByNameFailed");
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+//			LLFloaterGetBlockedObjectName
+//////////////////////////////////////////////////////////////////////////
+
+// Constructor/Destructor
+LLFloaterGetBlockedObjectName::LLFloaterGetBlockedObjectName(const LLSD& key)
+: LLFloater(key)
+, mGetObjectNameCallback(NULL)
+{
+}
+
+// Destroys the object
+LLFloaterGetBlockedObjectName::~LLFloaterGetBlockedObjectName()
+{
+	gFocusMgr.releaseFocusIfNeeded( this );
+}
+
+BOOL LLFloaterGetBlockedObjectName::postBuild()
+{
+	getChild<LLButton>("OK")->		setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::applyBlocking, this));
+	getChild<LLButton>("Cancel")->	setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::cancelBlocking, this));
+	center();
+
+	return LLFloater::postBuild();
+}
+
+BOOL LLFloaterGetBlockedObjectName::handleKeyHere(KEY key, MASK mask)
+{
+	if (key == KEY_RETURN && mask == MASK_NONE)
+	{
+		applyBlocking();
+		return TRUE;
+	}
+	else if (key == KEY_ESCAPE && mask == MASK_NONE)
+	{
+		cancelBlocking();
+		return TRUE;
+	}
+
+	return LLFloater::handleKeyHere(key, mask);
+}
+
+// static
+LLFloaterGetBlockedObjectName* LLFloaterGetBlockedObjectName::show(get_object_name_callback_t callback)
+{
+	LLFloaterGetBlockedObjectName* floater = LLFloaterReg::showTypedInstance<LLFloaterGetBlockedObjectName>("mute_object_by_name");
+
+	floater->mGetObjectNameCallback = callback;
+
+	// *TODO: mantipov: should LLFloaterGetBlockedObjectName be closed when panel is closed?
+	// old Floater dependency is not enable in panel
+	// addDependentFloater(floater);
+
+	return floater;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+void LLFloaterGetBlockedObjectName::applyBlocking()
+{
+	if (mGetObjectNameCallback)
+	{
+		const std::string& text = childGetValue("object_name").asString();
+		mGetObjectNameCallback(text);
+	}
+	closeFloater();
+}
+
+void LLFloaterGetBlockedObjectName::cancelBlocking()
+{
+	closeFloater();
+}
+
+//EOF
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
new file mode 100644
index 0000000000000000000000000000000000000000..52b74a184b57db364990754b26b33237140a378e
--- /dev/null
+++ b/indra/newview/llpanelblockedlist.h
@@ -0,0 +1,115 @@
+/** 
+ * @file llpanelblockedlist.h
+ * @brief Container for blocked Residents & Objects list
+ *
+ * $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_LLPANELBLOCKEDLIST_H
+#define LL_LLPANELBLOCKEDLIST_H
+
+#include "llpanel.h"
+#include "llmutelist.h"
+// #include <vector>
+
+// class LLButton;
+// class LLLineEditor;
+// class LLMessageSystem;
+// class LLUUID;
+ class LLScrollListCtrl;
+
+class LLPanelBlockedList
+	:	public LLPanel, public LLMuteListObserver
+{
+public:
+	LLPanelBlockedList();
+	~LLPanelBlockedList();
+
+	virtual BOOL postBuild();
+	virtual void draw();
+	virtual void onOpen(const LLSD& key);
+	
+	void selectBlocked(const LLUUID& id);
+
+	/**
+	 *	Shows current Panel in side tray and select passed blocked item.
+	 * 
+	 *	@param idToSelect - LLUUID of blocked Resident or Object to be selected. 
+	 *			If it is LLUUID::null, nothing will be selected.
+	 */
+	static void showPanelAndSelect(const LLUUID& idToSelect);
+
+	// LLMuteListObserver callback interface implementation.
+	/* virtual */ void onChange() {	refreshBlockedList();}
+	
+private:
+	void refreshBlockedList();
+	void updateButtons();
+
+	// UI callbacks
+	void onBackBtnClick();
+	void onRemoveBtnClick();
+	void onPickBtnClick();
+	void onBlockByNameClick();
+
+	static void callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
+	static void callbackBlockByName(const std::string& text);
+
+private:
+	LLScrollListCtrl* mBlockedList;
+};
+
+//-----------------------------------------------------------------------------
+// LLFloaterGetBlockedObjectName()
+//-----------------------------------------------------------------------------
+// Class for handling mute object by name floater.
+class LLFloaterGetBlockedObjectName : public LLFloater
+{
+	friend class LLFloaterReg;
+public:
+	typedef boost::function<void (const std::string&)> get_object_name_callback_t;
+
+	virtual BOOL postBuild();
+
+	virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+	static LLFloaterGetBlockedObjectName* show(get_object_name_callback_t callback);
+
+private:
+	LLFloaterGetBlockedObjectName(const LLSD& key);
+	virtual ~LLFloaterGetBlockedObjectName();
+
+	// UI Callbacks
+	void applyBlocking();
+	void cancelBlocking();
+
+	get_object_name_callback_t mGetObjectNameCallback;
+};
+
+
+#endif // LL_LLPANELBLOCKEDLIST_H
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 4cbb018ce9f5cfc17b780f0284417924cddafbc1..d1ce6b14edeeb9da4f31b247d751f5797699e032 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -298,6 +298,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
 	if(button_create)
 		button_create->setVisible(is_null_group_id);
 
+	getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id);
+
 	LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab");
 	LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab");
 	LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab");
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 73ea990b3feb1cc65a5e2b37a6724ccfcfd7d640..f3893a104c91641fc50d823b12cb16fb82b155d5 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -113,6 +113,7 @@ BOOL LLPanelGroupGeneral::postBuild()
 	if (mListVisibleMembers)
 	{
 		mListVisibleMembers->setDoubleClickCallback(openProfile, this);
+		mListVisibleMembers->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
 	}
 
 	// Options
@@ -769,11 +770,6 @@ void LLPanelGroupGeneral::updateMembers()
 		}
 		// Owners show up in bold.
 		std::string style = "NORMAL";
-		if ( member->isOwner() )
-		{
-			style = "BOLD";
-		}
-		
 		sd_timer.reset();
 		LLSD row;
 		row["id"] = member->getID();
@@ -793,7 +789,14 @@ void LLPanelGroupGeneral::updateMembers()
 		sSDTime += sd_timer.getElapsedTimeF32();
 
 		element_timer.reset();
-		mListVisibleMembers->addElement(row);//, ADD_SORTED);
+		LLScrollListItem* member_row = mListVisibleMembers->addElement(row);//, ADD_SORTED);
+		
+		if ( member->isOwner() )
+		{
+			LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
+			if (name_textp)
+				name_textp->setFontStyle(LLFontGL::BOLD);
+		}
 		sElementTime += element_timer.getElapsedTimeF32();
 	}
 	sAllTime += all_timer.getElapsedTimeF32();
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 4618b49df4e8730b7ab20fb1fcb63df655e03568..48c9c16780751e1392d706a8e3a7db814531c301 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -659,6 +659,12 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
 		row["columns"][1]["font"]["style"] = "BOLD";
 
 		LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData);
+		
+		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(title_row->getColumn(1));
+		if (name_textp)
+			name_textp->setFontStyle(LLFontGL::BOLD);
+
+
 
 		bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true;
 
@@ -837,6 +843,7 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
 	mMembersList->setCommitCallback(onMemberSelect, this);
 	// Show the member's profile on double click.
 	mMembersList->setDoubleClickCallback(onMemberDoubleClick, this);
+	mMembersList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
 
 	LLButton* button = parent->getChild<LLButton>("member_invite", recurse);
 	if ( button )
@@ -1731,6 +1738,8 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
 	mRolesList->setCommitOnSelectionChange(TRUE);
 	mRolesList->setCommitCallback(onRoleSelect, this);
 
+	mAssignedMembersList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
+
 	mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange, this);
 
 	mAllowedActionsList->setCommitOnSelectionChange(TRUE);
@@ -2397,6 +2406,7 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
 
 	mActionList->setCommitOnSelectionChange(TRUE);
 	mActionList->setCommitCallback(boost::bind(&LLPanelGroupActionsSubTab::handleActionSelect, this));
+	mActionList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
 
 	update(GC_ALL);
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 697182c8fc3dcf3b527a0f0a092d32e2c9f5f38c..42aa21c13ee866dcf809d43e5bb7e7ad509b9797 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -43,12 +43,12 @@
 
 // newview
 #include "llagent.h"
+#include "llavataractions.h"
 #include "llavatarlist.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llfloateravatarpicker.h"
 //#include "llfloaterminiinspector.h"
 #include "llfriendcard.h"
-#include "llavataractions.h"
 #include "llgroupactions.h"
 #include "llgrouplist.h"
 #include "llrecentpeople.h"
@@ -133,18 +133,23 @@ class LLAvatarListUpdater : public LLPanelPeople::Updater, public LLEventTimer
 class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 {
 	LOG_CLASS(LLFriendListUpdater);
+	class LLInventoryFriendCardObserver;
 
 public: 
+	friend class LLInventoryFriendCardObserver;
 	LLFriendListUpdater(callback_t cb)
 	:	LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT)
 	{
 		LLAvatarTracker::instance().addObserver(this);
+
 		// For notification when SIP online status changes.
 		LLVoiceClient::getInstance()->addObserver(this);
+		mInvObserver = new LLInventoryFriendCardObserver(this);
 	}
 
 	~LLFriendListUpdater()
 	{
+		delete mInvObserver;
 		LLVoiceClient::getInstance()->removeObserver(this);
 		LLAvatarTracker::instance().removeObserver(this);
 	}
@@ -166,6 +171,7 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 		mMask |= mask;
 	}
 
+
 	/*virtual*/ BOOL tick()
 	{
 		if (updateList(mMask))
@@ -180,6 +186,75 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 
 private:
 	U32 mMask;
+	LLInventoryFriendCardObserver* mInvObserver;
+
+	/**
+	 *	This class is intended for updating Friend List when Inventory Friend Card is added/removed.
+	 * 
+	 *	The main usage is when Inventory Friends/All content is added while synchronizing with 
+	 *		friends list on startup is performed. In this case Friend Panel should be updated when 
+	 *		missing Inventory Friend Card is created.
+	 *	*NOTE: updating is fired when Inventory item is added into CallingCards/Friends subfolder.
+	 *		Otherwise LLFriendObserver functionality is enough to keep Friends Panel synchronized.
+	 */
+	class LLInventoryFriendCardObserver : public LLInventoryObserver
+	{
+		LOG_CLASS(LLFriendListUpdater::LLInventoryFriendCardObserver);
+
+		friend class LLFriendListUpdater;
+
+	private:
+		LLInventoryFriendCardObserver(LLFriendListUpdater* updater) : mUpdater(updater)
+		{
+			gInventory.addObserver(this);
+		}
+		~LLInventoryFriendCardObserver()
+		{
+			gInventory.removeObserver(this);
+		}
+		/*virtual*/ void changed(U32 mask)
+		{
+			lldebugs << "Inventory changed: " << mask << llendl;
+
+			// *NOTE: deleting of InventoryItem is performed via moving to Trash. 
+			// That means LLInventoryObserver::STRUCTURE is present in MASK instead of LLInventoryObserver::REMOVE
+			if ((CALLINGCARD_ADDED & mask) == CALLINGCARD_ADDED)
+			{
+				lldebugs << "Calling card added: count: " << gInventory.getChangedIDs().size() 
+					<< ", first Inventory ID: "<< (*gInventory.getChangedIDs().begin())
+					<< llendl;
+
+				bool friendFound = false;
+				std::set<LLUUID> changedIDs = gInventory.getChangedIDs();
+				for (std::set<LLUUID>::const_iterator it = changedIDs.begin(); it != changedIDs.end(); ++it)
+				{
+					if (isDescendentOfInventoryFriends(*it))
+					{
+						friendFound = true;
+						break;
+					}
+				}
+
+				if (friendFound)
+				{
+					lldebugs << "friend found, panel should be updated" << llendl;
+					mUpdater->changed(LLFriendObserver::ADD);
+				}
+			}
+		}
+
+		bool isDescendentOfInventoryFriends(const LLUUID& invItemID)
+		{
+			LLViewerInventoryItem * item = gInventory.getItem(invItemID);
+			if (NULL == item)
+				return false;
+
+			return LLFriendCardsManager::instance().isItemInAnyFriendsList(item);
+		}
+		LLFriendListUpdater* mUpdater;
+
+		static const U32 CALLINGCARD_ADDED = LLInventoryObserver::ADD | LLInventoryObserver::CALLING_CARD;
+	};
 };
 
 /**
@@ -438,8 +513,13 @@ bool LLPanelPeople::updateFriendList(U32 changed_mask)
 		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;
+		}
 
 		LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
 		for (; buddy_it != all_buddies.end(); ++buddy_it)
@@ -896,7 +976,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
 	}
 }
 
-
 void LLPanelPeople::onCallButtonClicked()
 {
 	// *TODO: not implemented yet
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 973afae73b26991bca7014f46beb48a353ea8a64..c34038c672b215b16e3f05838f1d3457038b5a4f 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -46,6 +46,7 @@
 #include "llpanelprofile.h"
 #include "llpanelpick.h"
 #include "llscrollcontainer.h"
+#include "lllistctrl.h"
 
 static const std::string XML_BTN_NEW = "new_btn";
 static const std::string XML_BTN_DELETE = "trash_btn";
@@ -53,9 +54,10 @@ static const std::string XML_BTN_INFO = "info_btn";
 static const std::string XML_BTN_TELEPORT = "teleport_btn";
 static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
 
-static const std::string XML_PICKS_LIST = "back_panel";
+static const std::string PICK_ID("pick_id");
+static const std::string PICK_CREATOR_ID("pick_creator_id");
+static const std::string PICK_NAME("pick_name");
 
-#define PICK_ITEMS_BETWEEN 5
 
 static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
 
@@ -65,9 +67,9 @@ static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
 LLPanelPicks::LLPanelPicks()
 :	LLPanelProfileTab(),
 	mPopupMenu(NULL),
-	mSelectedPickItem(NULL),
 	mProfilePanel(NULL),
-	mPickPanel(NULL)
+	mPickPanel(NULL),
+	mPicksList(NULL)
 {
 }
 
@@ -100,22 +102,8 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 			gCacheName->getName(getAvatarId(),name,second_name);
 			childSetTextArg("pick_title", "[NAME]",name);
 
-			LLView* picks_list = getPicksList();
-			
-			// to restore selection of the same item later
-			LLUUID pick_id_selected(LLUUID::null);
-			if (mSelectedPickItem) pick_id_selected = mSelectedPickItem->getPickId();
-
-			clear();
-
-			//*TODO move it somewhere else?
-			picks_list->setEnabled(FALSE);
-			childSetEnabled(XML_BTN_NEW, false);
-			childSetEnabled(XML_BTN_DELETE, false);
-			childSetEnabled(XML_BTN_INFO, false);
-			childSetEnabled(XML_BTN_TELEPORT,!avatar_picks->picks_list.empty());
-			childSetEnabled(XML_BTN_SHOW_ON_MAP,!avatar_picks->picks_list.empty());
-						
+			mPicksList->clear();
+
 			LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
 			for(; avatar_picks->picks_list.end() != it; ++it)
 			{
@@ -124,109 +112,44 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 
 				LLPickItem* picture = LLPickItem::create();
 				picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
-				
-				picks_list->addChild(picture);
-
 				picture->setPickName(pick_name);
 				picture->setPickId(pick_id);
 				picture->setCreatorId(getAvatarId());
 
 				LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
 				picture->update();
-				mPickItemList.push_back(picture);
-				if (pick_id_selected != LLUUID::null && 
-					pick_id == pick_id_selected) setSelectedPickItem(picture);
+
+				LLSD pick_value = LLSD();
+				pick_value.insert(PICK_ID, pick_id);
+				pick_value.insert(PICK_NAME, pick_name);
+				pick_value.insert(PICK_CREATOR_ID, getAvatarId());
+
+				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->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 			}
 
-			reshapePicksList();
 			LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
-
 			updateButtons();
-			if (!mSelectedPickItem && mPickItemList.size()) setSelectedPickItem(mPickItemList.back());
-			picks_list->setEnabled(TRUE);
-
 		}
 	}
 }
 
-void LLPanelPicks::clear()
-{
-	LLView* scroll = getPicksList();
-	picture_list_t::const_iterator it = mPickItemList.begin();
-	for(; mPickItemList.end() != it; ++it)
-	{
-		scroll->removeChild(*it);
-		delete *it;
-	}
-	mPickItemList.clear();
-	mSelectedPickItem = NULL;
-}
-
-
 LLPickItem* LLPanelPicks::getSelectedPickItem()
 {
-	return mSelectedPickItem;
-}
-
-
-void LLPanelPicks::removePickItem( LLPickItem* pick_item )
-{
-	LLView* scroll = getPicksList();
-	scroll->removeChild(pick_item);
-	mPickItemList.remove(pick_item);
-	if (mPickItemList.size() == 0)
-	{
-		mSelectedPickItem = NULL;
-	}
-	else 
-	{
-		setSelectedPickItem(mPickItemList.back());
-	}
-
-	reshapePicksList();
-}
-
-void LLPanelPicks::reshapePicksList()
-{
-	if (!mPickItemList.size()) return;
-	LLView* pickList = getPicksList();
-
-	//We don't need to update size of the 'pick list' before reshaping pick items. Don't need to reshape the pick list
-	S32 height = mPickItemList.size() * (mPickItemList.front()->getRect().getHeight() + PICK_ITEMS_BETWEEN);
-	LLRect rc = pickList->getRect();
-	rc.setLeftTopAndSize(rc.mLeft, rc.mTop, rc.getWidth(), height);
-	pickList->setRect(rc);
+	LLPanel* selected_item = mPicksList->getSelectedItem();
+	if (!selected_item) return NULL;
 
-	S32 last_bottom = pickList->getRect().getHeight();
-	std::list<LLPickItem*>::const_iterator pick_it, pick_first_it = mPickItemList.begin();
-	for ( pick_it = pick_first_it; pick_it != mPickItemList.end(); ++pick_it)
-	{
-		LLView* const pick = *pick_it;
-		if(pick_it != pick_first_it)
-		{
-			last_bottom -= pick->getRect().getHeight();
-			last_bottom -= PICK_ITEMS_BETWEEN;
-		}
-		reshapePickItem(pick, last_bottom,pickList->getRect().getWidth());
-	}
-}
-
-void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth)
-{
-	LLRect rc = pick_item->getRect();
-	rc.mBottom = last_bottom - rc.getHeight();
-	rc.mTop = last_bottom;
-	pick_item->setRect(rc);
-	pick_item->reshape(newWidth, rc.getHeight());
-}
-
-LLView* LLPanelPicks::getPicksList() const
-{
-	return getChild<LLView>(XML_PICKS_LIST);
+	return dynamic_cast<LLPickItem*>(selected_item);
 }
 
 BOOL LLPanelPicks::postBuild()
 {
+	mPicksList = getChild<LLListCtrl>("picks_list");
+
 	childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
 
 	childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this));
@@ -270,6 +193,10 @@ void LLPanelPicks::onOpen(const LLSD& key)
 	{
 		childSetVisible("pick_title", !self);
 		childSetVisible("pick_title_agent", self);
+
+		mPopupMenu->setItemVisible("pick_delete", TRUE);
+		mPopupMenu->setItemVisible("pick_edit", TRUE);
+		mPopupMenu->setItemVisible("pick_separator", TRUE);
 	}
 
 	LLPanelProfileTab::onOpen(key);
@@ -278,11 +205,11 @@ void LLPanelPicks::onOpen(const LLSD& key)
 //static
 void LLPanelPicks::onClickDelete()
 {
-	LLPickItem* pick_item = getSelectedPickItem();
-	if (!pick_item) return;
+	LLSD pick_value = mPicksList->getSelectedValue();
+	if (pick_value.isUndefined()) return;
 
 	LLSD args; 
-	args["PICK"] = pick_item->getPickName(); 
+	args["PICK"] = pick_value[PICK_NAME]; 
 	LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2)); 
 }
 
@@ -290,12 +217,12 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response
 {
 	S32 option = LLNotification::getSelectedOption(notification, response);
 
-	LLPickItem* pick_item = getSelectedPickItem();
+	LLSD pick_value = mPicksList->getSelectedValue();
 
 	if (0 == option)
 	{
-		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId());
-		removePickItem(pick_item);
+		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
+		mPicksList->removeItemByValue(pick_value);
 	}
 	updateButtons();
 	return false;
@@ -329,101 +256,45 @@ void LLPanelPicks::onClickMap()
 }
 
 
-BOOL LLPanelPicks::handleRightMouseDown(S32 x, S32 y, MASK mask)
+void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
 {
-	if (isMouseInPick(x, y))
+	if (mPopupMenu)
 	{
-		if (mPopupMenu)
-		{
-			mPopupMenu->buildDrawLabels();
-			mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
-			((LLContextMenu*)mPopupMenu)->show(x, y);
-			LLMenuGL::showPopup(this, mPopupMenu, x, y);
-		}
-		return TRUE;
+		mPopupMenu->buildDrawLabels();
+		mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+		((LLContextMenu*)mPopupMenu)->show(x, y);
+		LLMenuGL::showPopup(item, mPopupMenu, x, y);
 	}
-	return LLPanel::handleRightMouseDown(x, y, mask);
 }
 
-BOOL LLPanelPicks::handleMouseDown( S32 x, S32 y, MASK mask )
+void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
 {
-	isMouseInPick(x, y);
-	return LLPanel::handleMouseDown(x, y, mask);
-}
-
-BOOL LLPanelPicks::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
-	if (isMouseInPick(x, y))
-	{
-		LLPickItem* pick_item = getSelectedPickItem();
-		if (pick_item) 
-		{
-			LLSD args; 
-			args["PICK"] = pick_item->getPickName(); 
-			LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
-		}
-		return TRUE;
-	}
-	return LLPanel::handleDoubleClick(x, y, mask);
+	LLSD pick_value = mPicksList->getSelectedValue();
+	if (pick_value.isUndefined()) return;
+	
+	LLSD args; 
+	args["PICK"] = pick_value[PICK_NAME]; 
+	LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); 
 }
 
 void LLPanelPicks::updateButtons()
 {
-	int picks_num = mPickItemList.size();
-	childSetEnabled(XML_BTN_INFO, picks_num > 0);
+	int picks_num = mPicksList->size();
+	bool has_selected = mPicksList->numSelected();
+
+	childSetEnabled(XML_BTN_INFO, has_selected);
 
 	if (getAvatarId() == gAgentID)
 	{
 		childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS);
-		childSetEnabled(XML_BTN_DELETE, picks_num > 0);
-
-		//*TODO move somewhere this calls
-		// we'd better set them up earlier when a panel was being constructed
-		mPopupMenu->setItemVisible("pick_delete", TRUE);
-		mPopupMenu->setItemVisible("pick_edit", TRUE);
-		mPopupMenu->setItemVisible("pick_separator", TRUE);
-	}
-
-	//*TODO update buttons like Show on Map, Teleport etc.
-
-}
-
-void LLPanelPicks::setSelectedPickItem(LLPickItem* item)
-{
-	if (!item) return;
-	if (mSelectedPickItem == item) return;
-	if (mSelectedPickItem && mSelectedPickItem->isBackgroundVisible())
-	{
-		mSelectedPickItem->setBackgroundVisible(FALSE);
+		childSetEnabled(XML_BTN_DELETE, has_selected);
 	}
-	item->setBackgroundVisible(TRUE);
-	mSelectedPickItem = item;
-}
 
-BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y )
-{
-	S32 x_l = x;
-	S32 y_l = y;
-	
-	if(!getChild<LLUICtrl>("profile_scroll")->getRect().pointInRect(x, y))
-	{
-		return FALSE;
-	}
-
-	picture_list_t::const_iterator it = mPickItemList.begin();
-	for(; mPickItemList.end() != it; ++it)
-	{
-		localPointToOtherView(x, y, &x_l, &y_l, (*it));
-		if ((*it)->pointInView(x_l, y_l))
-		{
-			setSelectedPickItem(*it);
-			return TRUE;
-		}
-	}	
-	return FALSE;
+	childSetEnabled(XML_BTN_INFO, has_selected);
+	childSetEnabled(XML_BTN_TELEPORT, has_selected);
+	childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected);
 }
 
-
 void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
 {
 	mProfilePanel = profile_panel;
@@ -449,12 +320,12 @@ void LLPanelPicks::onClickNew()
 
 void LLPanelPicks::onClickInfo()
 {
-	LLPickItem* pick = getSelectedPickItem();
-	if (!pick) return;
+	LLSD selected_value = mPicksList->getSelectedValue();
+	if (selected_value.isUndefined()) return;
 
 	buildPickPanel();
 	mPickPanel->reset();
-	mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+	mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
 	getProfilePanel()->togglePanel(mPickPanel);
 }
 
@@ -466,12 +337,12 @@ void LLPanelPicks::onClickBack()
 void LLPanelPicks::onClickMenuEdit()
 {
 	//*TODO, refactor - most of that is similar to onClickInfo
-	LLPickItem* pick = getSelectedPickItem();
-	if (!pick) return;
+	LLSD selected_value = mPicksList->getSelectedValue();
+	if (selected_value.isUndefined()) return;
 
 	buildPickPanel();
 	mPickPanel->reset();
-	mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+	mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
 	mPickPanel->setEditMode(TRUE);
 	getProfilePanel()->togglePanel(mPickPanel);
 }
@@ -601,3 +472,17 @@ void LLPanelPicks::onClose()
 		getProfilePanel()->togglePanel(mPickPanel);
 	}
 }
+
+BOOL LLPickItem::postBuild()
+{
+	setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", true));
+	setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", false));
+	return TRUE;
+}
+
+void LLPickItem::setValue(const LLSD& value)
+{
+	if (!value.isMap()) return;;
+	if (!value.has("selected")) return;
+	childSetVisible("selected_icon", value["selected"]);
+}
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index da7bc32ab12005e36f24b4713cc649ebb087c271..97e8e607c8094bfb7d651ee9cd7b5a4c5cc63994 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -48,7 +48,7 @@ class LLPanelPick;
 class LLAgent;
 class LLMenuGL;
 class LLPickItem;
-
+class LLListCtrl;
 
 class LLPanelPicks 
 	: public LLPanelProfileTab
@@ -67,18 +67,9 @@ class LLPanelPicks
 
 	void updateData();
 
-	void clear();
-
 	// returns the selected pick item
 	LLPickItem* getSelectedPickItem();
 
-	// removes the specified pick item
-	void removePickItem(LLPickItem* pick_item);
-
-	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-
 	//*NOTE top down approch when panel toggling is done only by 
 	// parent panels failed to work (picks related code was in me profile panel)
 	void setProfilePanel(LLPanelProfile* profile_panel);
@@ -106,25 +97,17 @@ class LLPanelPicks
 	bool callbackDelete(const LLSD& notification, const LLSD& response);
 	bool callbackTeleport(const LLSD& notification, const LLSD& response);
 
-	void reshapePicksList();
-	void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth);
-	LLView* getPicksList() const;
 	void updateButtons();
 
-	void setSelectedPickItem(LLPickItem* item);
-
-	BOOL isMouseInPick(S32 x, S32 y);
+	virtual void onDoubleClickItem(LLUICtrl* item);
+	virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
 
 	LLPanelProfile* getProfilePanel();
 
-
-	typedef std::list<LLPickItem*> picture_list_t;
-	picture_list_t mPickItemList;
-
 	LLMenuGL* mPopupMenu;
-	LLPickItem* mSelectedPickItem;
 	LLPanelProfile* mProfilePanel;
 	LLPanelPick* mPickPanel;
+	LLListCtrl* mPicksList;
 };
 
 class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
@@ -169,6 +152,11 @@ class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
 
 	~LLPickItem();
 
+	/*virtual*/ BOOL postBuild();
+
+	/** setting on/off background icon to indicate selected state */
+	/*virtual*/ void setValue(const LLSD& value);
+
 protected:
 
 	LLUUID mPickID;
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index a01977c9b517df744dbd9a46485f448b8406e835..ec1c10d8c9cb6583dadae97900385e9671bd0e8b 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -48,6 +48,8 @@
 #include "llscrollcontainer.h"
 #include "lltextbox.h"
 
+#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llfloaterworldmap.h"
@@ -80,6 +82,8 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo()
 	{
 		LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
 	}
+
+	LLViewerParcelMgr::getInstance()->removeObserver(this);
 }
 
 BOOL LLPanelPlaceInfo::postBuild()
@@ -93,14 +97,42 @@ BOOL LLPanelPlaceInfo::postBuild()
 	mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
 	mSnapshotCtrl->setEnabled(FALSE);
 
-	mRegionName = getChild<LLTextBox>("region_name");
-	mParcelName = getChild<LLTextBox>("parcel_name");
+	mRegionName = getChild<LLTextBox>("region_title");
+	mParcelName = getChild<LLTextBox>("parcel_title");
 	mDescEditor = getChild<LLTextEditor>("description");
-	mRating = getChild<LLIconCtrl>("maturity");
 
-	mRegionInfoDrillIn = getChild<LLButton>("region_info_drill_in");
-	mMediaDrillIn = getChild<LLButton>("media_drill_in");
-	mMediaDrillIn->setClickedCallback(boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, this, TRUE));
+	mMaturityRatingText = getChild<LLTextBox>("maturity_value");
+	mParcelOwner = getChild<LLTextBox>("owner_value");
+	mLastVisited = getChild<LLTextBox>("last_visited_value");
+
+	mRatingText = getChild<LLTextBox>("rating_value");
+	mVoiceText = getChild<LLTextBox>("voice_value");
+	mFlyText = getChild<LLTextBox>("fly_value");
+	mPushText = getChild<LLTextBox>("push_value");
+	mBuildText = getChild<LLTextBox>("build_value");
+	mScriptsText = getChild<LLTextBox>("scripts_value");
+	mDamageText = getChild<LLTextBox>("damage_value");
+
+	mRegionNameText = getChild<LLTextBox>("region_name");
+	mRegionTypeText = getChild<LLTextBox>("region_type");
+	mRegionRatingText = getChild<LLTextBox>("region_rating");
+	mRegionOwnerText = getChild<LLTextBox>("region_owner");
+	mRegionGroupText = getChild<LLTextBox>("region_group");
+
+	mEstateNameText = getChild<LLTextBox>("estate_name");
+	mEstateRatingText = getChild<LLTextBox>("estate_rating");
+	mEstateOwnerText = getChild<LLTextBox>("estate_owner");
+	mCovenantText = getChild<LLTextEditor>("covenant");
+
+	mSalesPriceText = getChild<LLTextBox>("sales_price");
+	mAreaText = getChild<LLTextBox>("area");
+	mTrafficText = getChild<LLTextBox>("traffic");
+	mPrimitivesText = getChild<LLTextBox>("primitives");
+	mParcelScriptsText = getChild<LLTextBox>("parcel_scripts");
+	mTerraformLimitsText = getChild<LLTextBox>("terraform_limits");
+	mSubdivideText = getChild<LLTextEditor>("subdivide");
+	mResaleText = getChild<LLTextEditor>("resale");
+	mSaleToText = getChild<LLTextBox>("sale_to");
 
 	mOwner = getChild<LLTextBox>("owner");
 	mCreator = getChild<LLTextBox>("creator");
@@ -224,7 +256,9 @@ void LLPanelPlaceInfo::resetLocation()
 	mLandmarkID.setNull();
 	mPosRegion.clearVec();
 	std::string not_available = getString("not_available");
-	mRating->setValue(not_available);
+	mMaturityRatingText->setValue(not_available);
+	mParcelOwner->setValue(not_available);
+	mLastVisited->setValue(not_available);
 	mRegionName->setText(not_available);
 	mParcelName->setText(not_available);
 	mDescEditor->setText(not_available);
@@ -235,6 +269,35 @@ void LLPanelPlaceInfo::resetLocation()
 	mNotesEditor->setText(LLStringUtil::null);
 	mSnapshotCtrl->setImageAssetID(LLUUID::null);
 	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
+
+	mRatingText->setText(not_available);
+	mVoiceText->setText(not_available);
+	mFlyText->setText(not_available);
+	mPushText->setText(not_available);
+	mBuildText->setText(not_available);
+	mParcelScriptsText->setText(not_available);
+	mDamageText->setText(not_available);
+
+	mRegionNameText->setValue(not_available);
+	mRegionTypeText->setValue(not_available);
+	mRegionRatingText->setValue(not_available);
+	mRegionOwnerText->setValue(not_available);
+	mRegionGroupText->setValue(not_available);
+
+	mEstateNameText->setValue(not_available);
+	mEstateRatingText->setValue(not_available);
+	mEstateOwnerText->setValue(not_available);
+	mCovenantText->setValue(not_available);
+
+	mSalesPriceText->setValue(not_available);
+	mAreaText->setValue(not_available);
+	mTrafficText->setValue(not_available);
+	mPrimitivesText->setValue(not_available);
+	mParcelScriptsText->setValue(not_available);
+	mTerraformLimitsText->setValue(not_available);
+	mSubdivideText->setValue(not_available);
+	mResaleText->setValue(not_available);
+	mSaleToText->setValue(not_available);
 }
 
 //virtual
@@ -251,12 +314,23 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 
 	bool is_info_type_agent = type == AGENT;
 	bool is_info_type_landmark = type == LANDMARK;
+	bool is_info_type_teleport_history = type == TELEPORT_HISTORY;
+
+	getChild<LLTextBox>("maturity_label")->setVisible(!is_info_type_agent);
+	mMaturityRatingText->setVisible(!is_info_type_agent);
+
+	getChild<LLTextBox>("owner_label")->setVisible(is_info_type_agent);
+	mParcelOwner->setVisible(is_info_type_agent);
+
+	getChild<LLTextBox>("last_visited_label")->setVisible(is_info_type_teleport_history);
+	mLastVisited->setVisible(is_info_type_teleport_history);
 
 	landmark_info_panel->setVisible(is_info_type_landmark);
 	landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK);
 
-	mRegionInfoDrillIn->setVisible(is_info_type_agent);
-	mMediaDrillIn->setVisible(is_info_type_agent);
+	getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
+
+	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
 
 	switch(type)
 	{
@@ -265,6 +339,15 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 		break;
 
 		case AGENT:
+			if (parcel_mgr)
+			{
+				// If information is requested for current agent location
+				// start using LLViewerParcelMgr for land selection.
+				parcel_mgr->addObserver(this);
+				parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
+			}
+
+		// Fall through to PLACE case
 		case PLACE:
 			mCurrentTitle = getString("title_place");
 
@@ -274,26 +357,35 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 			}
 		break;
 
-		// Hide Media Panel if showing information about
-		// a landmark or a teleport history item
 		case LANDMARK:
 			mCurrentTitle = getString("title_landmark");
 		break;
 
 		case TELEPORT_HISTORY:
-			mCurrentTitle = getString("title_place");
+			mCurrentTitle = getString("title_teleport_history");
 		break;
 	}
 
+	if (type != AGENT && parcel_mgr != NULL)
+	{
+		if (!parcel_mgr->selectionEmpty())
+		{
+			parcel_mgr->deselectUnused();
+		}
+		parcel_mgr->removeObserver(this);
+	}
+
 	if (type != PLACE)
 		toggleMediaPanel(FALSE);
+
+	mInfoType = type;
 }
 
 BOOL LLPanelPlaceInfo::isMediaPanelVisible()
 {
 	if (!mMediaPanel)
 		return FALSE;
-	
+
 	return mMediaPanel->getVisible();
 }
 
@@ -363,18 +455,17 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 	// HACK: Flag 0x2 == adult region,
 	// Flag 0x1 == mature region, otherwise assume PG
 	std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
-	std::string rating_icon = "icon_event.tga";
 	if (parcel_data.flags & 0x2)
 	{
 		rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
-		rating_icon = "icon_event_adult.tga";
 	}
 	else if (parcel_data.flags & 0x1)
 	{
 		rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
-		rating_icon = "icon_event_mature.tga";
 	}
-	mRating->setValue(rating_icon);
+
+	mMaturityRatingText->setValue(rating);
+	mRatingText->setValue(rating);
 
 	//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE
 	//because we deal with remote parcel response format
@@ -402,7 +493,7 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mRegionName->setText(name);
 	}
 	
-	if (mCurrentTitle != getString("title_landmark"))
+	if (mInfoType == CREATE_LANDMARK)
 	{
 		mTitleEditor->setText(parcel_data.name);
 		mNotesEditor->setText(LLStringUtil::null);
@@ -443,13 +534,21 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
 
 void LLPanelPlaceInfo::displayAgentParcelInfo()
 {
-	mPosRegion = gAgent.getPositionAgent();
+	mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
 
-	LLViewerRegion* region = gAgent.getRegion();
-	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+	LLParcel* parcel = mParcel->getParcel();
+	LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
 	if (!region || !parcel)
 		return;
 
+	// send EstateCovenantInfo message
+	LLMessageSystem *msg = gMessageSystem;
+	msg->newMessage("EstateCovenantRequest");
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
+	msg->sendReliable(region->getHost());
+
 	LLParcelData parcel_data;
 
 	// HACK: Converting sim access flags to the format
@@ -465,13 +564,6 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
 	default:
 		parcel_data.flags = 0;
 	}
-	
-	// Adding "For Sale" flag in remote parcel response format.
-	if (parcel->getForSale())
-	{
-		parcel_data.flags |= DFQ_FOR_SALE;
-	}
-	
 	parcel_data.desc = parcel->getDesc();
 	parcel_data.name = parcel->getName();
 	parcel_data.sim_name = gAgent.getRegion()->getName();
@@ -481,9 +573,241 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
 	parcel_data.global_y = global_pos.mdV[1];
 	parcel_data.global_z = global_pos.mdV[2];
 
-	
+	mPosRegion = gAgent.getPositionAgent();
 
 	processParcelInfo(parcel_data);
+
+	std::string on = getString("on");
+	std::string off = getString("off");
+
+	// Processing parcel characteristics
+	if (parcel->getParcelFlagAllowVoice())
+	{
+		mVoiceText->setText(on);
+	}
+	else
+	{
+		mVoiceText->setText(off);
+	}
+	
+	if (!region->getBlockFly() && parcel->getAllowFly())
+	{
+		mFlyText->setText(on);
+	}
+	else
+	{
+		mFlyText->setText(off);
+	}
+
+	if (region->getRestrictPushObject() || parcel->getRestrictPushObject())
+	{
+		mPushText->setText(off);
+	}
+	else
+	{
+		mPushText->setText(on);
+	}
+
+	if (parcel->getAllowModify())
+	{
+		mBuildText->setText(on);
+	}
+	else
+	{
+		mBuildText->setText(off);
+	}
+
+	if((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) ||
+	   (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) ||
+	   !parcel->getAllowOtherScripts())
+	{
+		mScriptsText->setText(off);
+	}
+	else
+	{
+		mScriptsText->setText(on);
+	}
+
+	if (region->getAllowDamage() || parcel->getAllowDamage())
+	{
+		mDamageText->setText(on);
+	}
+	else
+	{
+		mDamageText->setText(off);
+	}
+
+	mRegionNameText->setText(region->getName());
+	mRegionTypeText->setText(region->getSimProductName());
+	mRegionRatingText->setText(region->getSimAccessString());
+
+	// Determine parcel owner
+	if (parcel->isPublic())
+	{
+		mParcelOwner->setText(getString("public"));
+		mRegionOwnerText->setText(getString("public"));
+	}
+	else
+	{
+		if (parcel->getIsGroupOwned())
+		{
+			mRegionOwnerText->setText(getString("group_owned_text"));
+
+			if(!parcel->getGroupID().isNull())
+			{
+				// FIXME: Using parcel group as region group.
+				gCacheName->get(parcel->getGroupID(), TRUE,
+								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionGroupText, _2, _3));
+
+				gCacheName->get(parcel->getGroupID(), TRUE,
+								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3));
+			}
+			else
+			{
+				std::string owner = getString("none_text");
+				mRegionGroupText->setText(owner);
+				mParcelOwner->setText(owner);
+			}
+		}
+		else
+		{
+			// Figure out the owner's name
+			gCacheName->get(parcel->getOwnerID(), FALSE,
+							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3));
+			gCacheName->get(region->getOwner(), FALSE,
+							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionOwnerText, _2, _3));
+		}
+
+		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
+		{
+			mRegionOwnerText->setText(mRegionOwnerText->getText() + getString("sale_pending_text"));
+		}
+	}
+
+	mEstateRatingText->setText(region->getSimAccessString());
+
+	S32 area;
+	S32 claim_price;
+	S32 rent_price;
+	F32 dwell;
+	BOOL for_sale = parcel->getForSale();
+	LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
+													 &claim_price,
+													 &rent_price,
+													 &for_sale,
+													 &dwell);
+
+	if (for_sale)
+	{
+		// Adding "For Sale" flag in remote parcel response format.
+		parcel_data.flags |= DFQ_FOR_SALE;
+
+		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
+		if(auth_buyer_id.notNull())
+		{
+			gCacheName->get(auth_buyer_id, TRUE,
+							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mSaleToText, _2, _3));
+
+			// Show sales info to a specific person or a group he belongs to.
+			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
+			{
+				for_sale = FALSE;
+			}
+		}
+		else
+		{
+			mSaleToText->setText(getString("anyone"));
+		}
+
+		const U8* sign = (U8*)getString("price_text").c_str();
+		const U8* sqm = (U8*)getString("area_text").c_str();
+
+		mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice()));
+		mAreaText->setText(llformat("%d %s", area, sqm));
+		mTrafficText->setText(llformat("%.0f", dwell));
+
+		// Can't have more than region max tasks, regardless of parcel
+		// object bonus factor.
+		S32 primitives = llmin(llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()),
+							   (S32)region->getMaxTasks());
+
+		const U8* available = (U8*)getString("available").c_str();
+		const U8* allocated = (U8*)getString("allocated").c_str();
+
+		mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated));
+
+		if (parcel->getAllowOtherScripts())
+		{
+			mParcelScriptsText->setText(getString("all_residents_text"));
+		}
+		else if (parcel->getAllowGroupScripts())
+		{
+			mParcelScriptsText->setText(getString("group_text"));
+		}
+		else
+		{
+			mParcelScriptsText->setText(off);
+		}
+
+		mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off);
+
+		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		{
+			mSubdivideText->setText(getString("can_change"));
+		}
+		else
+		{
+			mSubdivideText->setText(getString("can_not_change"));
+		}
+		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		{
+			mResaleText->setText(getString("can_not_resell"));
+		}
+		else
+		{
+			mResaleText->setText(getString("can_resell"));
+		}
+	}
+
+	getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
+}
+
+// virtual
+void LLPanelPlaceInfo::changed()
+{
+	resetLocation();
+	displayAgentParcelInfo();
+}
+
+void LLPanelPlaceInfo::updateEstateName(const std::string& name)
+{
+	mEstateNameText->setText(name);
+}
+
+void LLPanelPlaceInfo::updateEstateOwnerName(const std::string& name)
+{
+	mEstateOwnerText->setText(name);
+}
+
+void LLPanelPlaceInfo::updateCovenantText(const std::string &text)
+{
+	mCovenantText->setText(text);
+}
+
+void LLPanelPlaceInfo::updateLastVisitedText(const LLDate &date)
+{
+	if (date.isNull())
+	{
+		mLastVisited->setText(getString("unknown"));
+	}
+	else
+	{
+		std::string timeStr = getString("acquired_date");
+		LLSD substitution;
+		substitution["datetime"] = (S32) date.secondsSinceEpoch();
+		LLStringUtil::format (timeStr, substitution);
+		mLastVisited->setText(timeStr);
+	}
 }
 
 void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
@@ -573,6 +897,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
 	LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO);
 }
 
+// virtual
 void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
 	if (mMinHeight > 0 && mScrollingPanel != NULL)
@@ -582,3 +907,22 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 	LLView::reshape(width, height, called_from_parent);
 }
+
+// virtual
+void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility)
+{
+	LLPanel::handleVisibilityChange(new_visibility);
+
+	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+	if (!parcel_mgr)
+		return;
+
+	// Remove land selection when panel hides.
+	if (!new_visibility)
+	{
+		if (!parcel_mgr->selectionEmpty())
+		{
+			parcel_mgr->deselectLand();
+		}
+	}
+}
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 77ce2c66196b95bd59842024255824d0cea4f87e..60f35cd0c123e50c6e4b257021988520a46ca27c 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -42,15 +42,17 @@
 
 #include "llpanelmedia.h"
 #include "llremoteparcelrequest.h"
+#include "llviewerparcelmgr.h"
 
 class LLButton;
 class LLInventoryItem;
 class LLLineEditor;
+class LLParcelSelection;
 class LLTextBox;
 class LLTextEditor;
 class LLTextureCtrl;
 
-class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
+class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver
 {
 public:
 	enum INFO_TYPE
@@ -105,12 +107,21 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	// without sending a request to the server.
 	void displayAgentParcelInfo();
 
+	// Called on parcel selection change by LLViewerParcelMgr.
+	/*virtual*/ void changed();
+
+	void updateEstateName(const std::string& name);
+	void updateEstateOwnerName(const std::string& name);
+	void updateCovenantText(const std::string &text);
+	void updateLastVisitedText(const LLDate &date);
+
 	void nameUpdatedCallback(LLTextBox* text,
 							 const std::string& first,
 							 const std::string& last);
 
 	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+	/*virtual*/ void handleVisibilityChange (BOOL new_visibility);
 
 private:
 	enum LANDMARK_INFO_TYPE
@@ -127,24 +138,56 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	LLVector3		mPosRegion;
 	std::string		mCurrentTitle;
 	S32				mMinHeight;
+	INFO_TYPE 		mInfoType;
 
 	LLTextBox*			mTitle;
 	LLTextureCtrl*		mSnapshotCtrl;
 	LLTextBox*			mRegionName;
 	LLTextBox*			mParcelName;
 	LLTextEditor*		mDescEditor;
-	LLIconCtrl*			mRating;
-	LLButton*			mRegionInfoDrillIn;
-	LLButton*			mMediaDrillIn;
+	LLTextBox*			mMaturityRatingText;
+	LLTextBox*			mParcelOwner;
+	LLTextBox*			mLastVisited;
+
+	LLTextBox*			mRatingText;
+	LLTextBox*			mVoiceText;
+	LLTextBox*			mFlyText;
+	LLTextBox*			mPushText;
+	LLTextBox*			mBuildText;
+	LLTextBox*			mScriptsText;
+	LLTextBox*			mDamageText;
+
+	LLTextBox*			mRegionNameText;
+	LLTextBox*			mRegionTypeText;
+	LLTextBox*			mRegionRatingText;
+	LLTextBox*			mRegionOwnerText;
+	LLTextBox*			mRegionGroupText;
+
+	LLTextBox*			mEstateNameText;
+	LLTextBox*			mEstateRatingText;
+	LLTextBox*			mEstateOwnerText;
+	LLTextEditor*		mCovenantText;
+
+	LLTextBox*			mSalesPriceText;
+	LLTextBox*			mAreaText;
+	LLTextBox*			mTrafficText;
+	LLTextBox*			mPrimitivesText;
+	LLTextBox*			mParcelScriptsText;
+	LLTextBox*			mTerraformLimitsText;
+	LLTextEditor*		mSubdivideText;
+	LLTextEditor*		mResaleText;
+	LLTextBox*			mSaleToText;
+
 	LLTextBox*			mOwner;
 	LLTextBox*			mCreator;
 	LLTextBox*			mCreated;
 	LLLineEditor*		mTitleEditor;
 	LLTextEditor*		mNotesEditor;
-	LLTextBox*			mLocationEditor;
 	LLPanel*            mScrollingPanel;
 	LLPanel*			mInfoPanel;
 	LLMediaPanel*		mMediaPanel;
+
+	LLSafeHandle<LLParcelSelection>	mParcel;
 };
 
 #endif // LL_LLPANELPLACEINFO_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 7cb9e61e72f9653c495502ff913bf7589f3a3e10..bc740bd865ad76491cdb4d494c799297a95b5f33 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -51,6 +51,7 @@
 #include "llpanellandmarks.h"
 #include "llpanelteleporthistory.h"
 #include "llsidetray.h"
+#include "llteleporthistorystorage.h"
 #include "lltoggleablemenu.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
@@ -119,9 +120,6 @@ BOOL LLPanelPlaces::postBuild()
 	//mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this));
 
 	mOverflowBtn = getChild<LLButton>("overflow_btn");
-
-	// *TODO: Assign the action to an appropriate event.
-	//mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));
 	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
 
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -156,20 +154,17 @@ BOOL LLPanelPlaces::postBuild()
 	LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn");
 	back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 
-	// *TODO: Assign the action to an appropriate event.
-	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));
-
 	return TRUE;
 }
 
 void LLPanelPlaces::onOpen(const LLSD& key)
 {
-	mFilterEditor->clear();
-	onFilterEdit("");
-	
 	if(mPlaceInfo == NULL || key.size() == 0)
 		return;
 
+	mFilterEditor->clear();
+	onFilterEdit("");
+
 	mPlaceInfoType = key["type"].asString();
 	mPosGlobal.setZero();
 	togglePlaceInfoPanel(TRUE);
@@ -178,8 +173,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	if (mPlaceInfoType == AGENT_INFO_TYPE)
 	{
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT);
-		mPlaceInfo->displayAgentParcelInfo();
-		
+
 		mPosGlobal = gAgent.getPositionGlobal();
 	}
 	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
@@ -218,18 +212,17 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	{
 		S32 index = key["id"].asInteger();
 
-		const LLTeleportHistory::slurl_list_t& hist_items =
-			LLTeleportHistory::getInstance()->getItems();
+		const LLTeleportHistoryStorage::slurl_list_t& hist_items =
+					LLTeleportHistoryStorage::getInstance()->getItems();
 
 		mPosGlobal = hist_items[index].mGlobalPos;
 
 		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
+		mPlaceInfo->updateLastVisitedText(hist_items[index].mDate);
 		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
-									  hist_items[index].mRegionID,
+									  LLUUID(),
 									  mPosGlobal);
 	}
-	
-
 }
 
 void LLPanelPlaces::setItem(LLInventoryItem* item)
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 089a854762040672528e5aa4cef66b50f74d89fe..057c4302301b5e3bc918adb66176eb9d42c72d8d 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -79,7 +79,7 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 
 	void onAgentParcelChange();
 	void updateVerbs();
-	
+
 	void showLandmarkFoldersMenu();
 
 	LLFilterEditor*				mFilterEditor;
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index 18184a6476835fa54db15bb04b2043c7bbd49ae1..0762bbeb875e7a7accb613fa1c8f092a1bec7a49 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -31,12 +31,16 @@
 */
 
 #include "llviewerprecompiledheaders.h"
+
+#include "lluserrelations.h"
+
 #include "llpanelprofileview.h"
 
+#include "llcallingcard.h"
 #include "llpanelavatar.h"
 #include "llpanelpicks.h"
-#include "llsidetraypanelcontainer.h"
 #include "llpanelprofile.h"
+#include "llsidetraypanelcontainer.h"
 
 static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view");
 
@@ -45,6 +49,7 @@ static const std::string PANEL_PROFILE = "panel_profile";
 
 LLPanelProfileView::LLPanelProfileView()
 :	LLPanelProfile()
+,	mStatusText(NULL)
 {
 }
 
@@ -65,6 +70,10 @@ void LLPanelProfileView::onOpen(const LLSD& key)
 		setAvatarId(id);
 	}
 
+	// status should only show if viewer has permission to view online/offline. EXT-453 
+	mStatusText->setVisible(isGrantedToSeeOnlineStatus());
+	updateOnlineStatus();
+
 	LLPanelProfile::onOpen(key);
 }
 
@@ -78,6 +87,8 @@ BOOL LLPanelProfileView::postBuild()
 	getTabContainer()[PANEL_PROFILE]->childSetVisible("online_me_status_text", FALSE);
 	getTabContainer()[PANEL_PROFILE]->childSetVisible("status_combo", FALSE);
 
+	mStatusText = getChild<LLTextBox>("status");
+
 	childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL);
 	
 	return TRUE;
@@ -94,3 +105,32 @@ void LLPanelProfileView::onBackBtnClick()
 		parent->openPreviousPanel();
 	}
 }
+
+bool LLPanelProfileView::isGrantedToSeeOnlineStatus()
+{
+	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+	if (NULL == relationship)
+		return false;
+
+	// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status.
+	// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer
+	// see comments for ChangeUserRights template message. EXT-453.
+//	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
+	return true;
+}
+
+void LLPanelProfileView::updateOnlineStatus()
+{
+	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+	if (NULL == relationship)
+		return;
+
+	bool online = relationship->isOnline();
+//	std::string statusName();
+
+	std::string status = getString(online ? "status_online" : "status_offline");
+
+	mStatusText->setValue(status);
+}
+
+// EOF
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 92def7b7ca4987116e86b48f80a1525caeba61e2..533ab94cc33e9130a4a55df1b6597bbd66e061dd 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -39,7 +39,7 @@
 
 class LLPanelProfile;
 class LLPanelProfileTab;
-
+class LLTextBox;
 
 /**
 * Panel for displaying Avatar's profile. It consists of three sub panels - Profile,
@@ -63,6 +63,11 @@ class LLPanelProfileView : public LLPanelProfile
 protected:
 
 	void onBackBtnClick();
+	bool isGrantedToSeeOnlineStatus();
+	void updateOnlineStatus();
+
+private:
+	LLTextBox* mStatusText;
 };
 
 #endif //LL_LLPANELPROFILEVIEW_H
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 8b378c33e35df8c2ff7b3111585779aa1d4ad1b6..df48ee5d0821d2a9d19baad783e6cd715c832921 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -37,6 +37,7 @@
 #include "llpanelteleporthistory.h"
 #include "llsidetray.h"
 #include "llworldmap.h"
+#include "llteleporthistorystorage.h"
 
 // Not yet implemented; need to remove buildPanel() from constructor when we switch
 //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -56,7 +57,7 @@ LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
 
 BOOL LLTeleportHistoryPanel::postBuild()
 {
-	mTeleportHistory = LLTeleportHistory::getInstance();
+	mTeleportHistory = LLTeleportHistoryStorage::getInstance();
 	if (mTeleportHistory)
 	{
 		mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this));
@@ -92,9 +93,7 @@ void LLTeleportHistoryPanel::onShowOnMap()
 
 	S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
 
-	const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
-
-	LLVector3d global_pos = hist_items[index].mGlobalPos;
+	LLVector3d global_pos = mTeleportHistory->getItems()[index].mGlobalPos;
 	
 	if (!global_pos.isExactlyZero())
 	{
@@ -153,7 +152,7 @@ void LLTeleportHistoryPanel::updateVerbs()
 	if (itemp)
 	{
 		index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
-		cur_item = mTeleportHistory->getCurrentItemIndex();
+		cur_item = mTeleportHistory->getItems().size() - 1;
 	}
 
 	mTeleportBtn->setEnabled(index != cur_item);
@@ -162,13 +161,11 @@ void LLTeleportHistoryPanel::updateVerbs()
 
 void LLTeleportHistoryPanel::showTeleportHistory()
 {
-	const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
+	const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems();
 
 	mHistoryItems->deleteAllItems();
 
-	S32 cur_item = mTeleportHistory->getCurrentItemIndex();
-
-	for (LLTeleportHistory::slurl_list_t::const_iterator iter = hist_items.begin();
+	for (LLTeleportHistoryStorage::slurl_list_t::const_iterator iter = hist_items.begin();
 				iter != hist_items.end(); ++iter)
 	{
 		std::string landmark_title = (*iter).mTitle;
@@ -181,7 +178,6 @@ void LLTeleportHistoryPanel::showTeleportHistory()
 			continue;
 
 		S32 index = iter - hist_items.begin();
-
 		LLSD row;
 		row["id"] = index;
 
@@ -201,14 +197,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
 		index_column["value"] = index;
 
 		mHistoryItems->addElement(row, ADD_TOP);
-
-		if (cur_item == index)
-		{
-			LLScrollListItem* itemp = mHistoryItems->getItem(index);
-			((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD);
-		}
 	}
 
+	// Consider last item (most recent) as current
+	LLScrollListItem* itemp = mHistoryItems->getItem((S32)hist_items.size() - 1);
+	((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD);
+
 	updateVerbs();
 }
 
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 553385b37e7db9125110d28b1e6069f7a73b916a..023b04c3facb9d64ba8d654f516962305eb3204d 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -39,6 +39,8 @@
 #include "llpanelplacestab.h"
 #include "llteleporthistory.h"
 
+class LLTeleportHistoryStorage;
+
 class LLTeleportHistoryPanel : public LLPanelPlacesTab
 {
 public:
@@ -65,7 +67,7 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab
 		LIST_INDEX
 	};
 
-	LLTeleportHistory*		mTeleportHistory;
+	LLTeleportHistoryStorage*	mTeleportHistory;
 	LLScrollListCtrl*		mHistoryItems;
 	std::string				mFilterSubString;
 };
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index cadab71ba840c4d034b5331a1867c75a275e8baf..29320522d92653cc7606926979f0b7c3ad796a0a 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -87,6 +87,7 @@ BOOL LLPreviewNotecard::postBuild()
 	LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
 	if (ed)
 	{
+		ed->setParseHTML(TRUE);
 		ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
 		ed->makePristine();
 	}
@@ -126,7 +127,7 @@ void LLPreviewNotecard::draw()
 {
 	LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
 	BOOL changed = !editor->isPristine();
-	
+
 	childSetEnabled("Save", changed && getEnabled());
 	
 	LLPreview::draw();
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index f70cfc59ec79ebfefc9e3064742b6088c5202000..aa603c417f1e66d45751d5d016264648e1e64cbc 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -72,7 +72,6 @@ const S32 ANIMATION_FRAMES = 1; //13;
 LLProgressView::LLProgressView(const LLRect &rect) 
 :	LLPanel(),
 	mPercentDone( 0.f ),
-	mURLInMessage(false),
 	mMouseDownInActiveArea( false )
 {
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_progress.xml");
@@ -207,12 +206,7 @@ void LLProgressView::setPercent(const F32 percent)
 void LLProgressView::setMessage(const std::string& msg)
 {
 	mMessage = msg;
-	mURLInMessage = (mMessage.find( "https://" ) != std::string::npos ||
-			 mMessage.find( "http://" ) != std::string::npos ||
-			 mMessage.find( "ftp://" ) != std::string::npos);
-
 	getChild<LLTextBox>("message_text")->setWrappedText(LLStringExplicit(mMessage));
-	getChild<LLTextBox>("message_text")->setHoverActive(mURLInMessage);
 }
 
 void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label)
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 83574ff52ad5526037755c876788875d58a45dff..865646c85d0b036c35bbe9864704847273851210 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -74,7 +74,6 @@ class LLProgressView : public LLPanel
 	LLFrameTimer mProgressTimer;
 	LLRect mOutlineRect;
 	bool mMouseDownInActiveArea;
-	bool mURLInMessage;
 
 	static LLProgressView* sInstance;
 };
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 68996673be893fbb2b5bbb9059dfbd0d1860ff7a..1fbe3592959a80557d6ad88347572cf21601eb2f 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -88,9 +88,12 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
 //--------------------------------------------------------------------------
 void LLScreenChannel::addToast(LLToast::Params p)
 {
-	bool store_toast = !mShowToasts && p.can_be_stored && mCanStoreToasts;
+	bool store_toast = false, show_toast = false;
 
-	if(!mShowToasts && !store_toast)
+	show_toast = mShowToasts || p.force_show;
+	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
+
+	if(!show_toast && !store_toast)
 	{
 		mOnRejectToast(p);
 		return;
@@ -106,7 +109,7 @@ void LLScreenChannel::addToast(LLToast::Params p)
 		new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
 	}
 	
-	if(mShowToasts)
+	if(show_toast)
 	{
 		mToastList.push_back(new_toast_elem);
 		showToasts();
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c903f40f3febee28b883db64e7b1e8c07b577dbf
--- /dev/null
+++ b/indra/newview/llsearchcombobox.cpp
@@ -0,0 +1,250 @@
+/**
+ * @file llsearchcombobox.cpp
+ * @brief Search Combobox 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 "llsearchcombobox.h"
+
+#include "llkeyboard.h"
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLSearchComboBox> r1("search_combo_box");
+
+class LLSearchHistoryBuilder
+{
+public:
+	LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter);
+
+	virtual void buildSearchHistory();
+
+	virtual ~LLSearchHistoryBuilder(){}
+
+protected:
+
+	virtual bool filterSearchHistory();
+
+	LLSearchComboBox* mComboBox;
+	std::string mFilter;
+	LLSearchHistory::search_history_list_t mFilteredSearchHistory;
+};
+
+LLSearchComboBox::Params::Params()
+: search_button("search_button")
+, dropdown_button_visible("dropdown_button_visible", false)
+{
+}
+
+LLSearchComboBox::LLSearchComboBox(const Params&p)
+: LLComboBox(p)
+{
+	S32 btn_top = p.search_button.top_pad + p.search_button.rect.height;
+	S32 btn_right = p.search_button.rect.width + p.search_button.left_pad;
+	LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad);
+
+	LLButton::Params button_params(p.search_button);
+	button_params.name(std::string("search_btn"));
+	button_params.rect(search_btn_rect) ;
+	button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP);
+	button_params.tab_stop(false);
+	button_params.click_callback.function(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
+	mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
+	mTextEntry->addChild(mSearchButton);
+
+	setButtonVisible(p.dropdown_button_visible);
+	mTextEntry->setCommitCallback(boost::bind(&LLComboBox::onTextCommit, this, _2));
+	mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL);
+	setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
+	setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2));
+}
+
+void LLSearchComboBox::rebuildSearchHistory(const std::string& filter)
+{
+	LLSearchHistoryBuilder builder(this, filter);
+	builder.buildSearchHistory();
+}
+
+void LLSearchComboBox::onSearchPrearrange(const LLSD& data)
+{
+	std::string filter = data.asString();
+	rebuildSearchHistory(filter);
+
+	mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
+}
+
+void LLSearchComboBox::onTextEntry(LLLineEditor* line_editor)
+{
+	KEY key = gKeyboard->currentKey();
+
+	if (line_editor->getText().empty())
+	{
+		prearrangeList(); // resets filter
+		hideList();
+	}
+	// Typing? (moving cursor should not affect showing the list)
+	else if (key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
+	{
+		prearrangeList(line_editor->getText());
+		if (mList->getItemCount() != 0)
+		{
+			showList();
+			focusTextEntry();
+		}
+		else
+		{
+			// Hide the list if it's empty.
+			hideList();
+		}
+	}
+	LLComboBox::onTextEntry(line_editor);
+}
+
+void LLSearchComboBox::focusTextEntry()
+{
+	// We can't use "mTextEntry->setFocus(TRUE)" instead because
+	// if the "select_on_focus" parameter is true it places the cursor
+	// at the beginning (after selecting text), thus screwing up updateSelection().
+	if (mTextEntry)
+	{
+		gFocusMgr.setKeyboardFocus(mTextEntry);
+	}
+}
+
+void LLSearchComboBox::hideList()
+{
+	LLComboBox::hideList();
+	if (mTextEntry && hasFocus())
+		focusTextEntry();
+}
+
+LLSearchComboBox::~LLSearchComboBox()
+{
+}
+
+void LLSearchComboBox::onSelectionCommit()
+{
+	std::string search_query = getSimple();
+	LLStringUtil::trim(search_query);
+	if(search_query.empty())
+	{
+		mTextEntry->setText(search_query);
+		setControlValue(search_query);
+
+		return;
+	}
+
+	remove(search_query);
+	add(search_query, ADD_TOP);
+	mTextEntry->setText(search_query);
+	setControlValue(search_query);
+
+	LLUICtrl::onCommit();
+}
+
+BOOL LLSearchComboBox::remove(const std::string& name)
+{
+	BOOL found = mList->selectItemByLabel(name, FALSE);
+
+	if (found)
+	{
+		LLScrollListItem* item = mList->getFirstSelected();
+		if (item)
+		{
+			LLComboBox::remove(mList->getItemIndex(item));
+		}
+	}
+
+	return found;
+}
+
+void LLSearchComboBox::clearHistory()
+{
+	removeall();
+	setTextEntry(LLStringUtil::null);
+}
+
+LLSearchHistoryBuilder::LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter)
+: mComboBox(combo_box)
+, mFilter(filter)
+{
+}
+
+bool LLSearchHistoryBuilder::filterSearchHistory()
+{
+	// *TODO: an STL algorithm would look nicer
+	mFilteredSearchHistory.clear();
+
+	std::string filter_copy = mFilter;
+	LLStringUtil::toLower(filter_copy);
+
+	LLSearchHistory::search_history_list_t history = 
+		LLSearchHistory::getInstance()->getSearchHistoryList();
+
+	LLSearchHistory::search_history_list_t::const_iterator it = history.begin();
+	for ( ; it != history.end(); ++it)
+	{
+		std::string search_query = (*it).search_query;
+		LLStringUtil::toLower(search_query);
+
+		if (search_query.find(filter_copy) != std::string::npos)
+			mFilteredSearchHistory.push_back(*it);
+	}
+
+	return mFilteredSearchHistory.size();
+}
+
+void LLSearchHistoryBuilder::buildSearchHistory()
+{
+	mFilteredSearchHistory.clear();
+
+	LLSearchHistory::search_history_list_t filtered_items;
+	LLSearchHistory::search_history_list_t* itemsp = NULL;
+	LLSearchHistory* sh = LLSearchHistory::getInstance();
+
+	if (mFilter.empty())
+	{
+		itemsp = &sh->getSearchHistoryList();
+	}
+	else
+	{
+		filterSearchHistory();
+		itemsp = &mFilteredSearchHistory;
+		itemsp->sort();
+	}
+
+	mComboBox->removeall();
+
+	LLSearchHistory::search_history_list_t::const_iterator it = itemsp->begin();
+	for ( ; it != itemsp->end(); it++)
+	{
+		LLSearchHistory::LLSearchHistoryItem item = *it;
+		mComboBox->add(item.search_query);
+	}
+}
diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h
new file mode 100644
index 0000000000000000000000000000000000000000..38f9a5a26be62dba34ae6414336f75af77ef8448
--- /dev/null
+++ b/indra/newview/llsearchcombobox.h
@@ -0,0 +1,108 @@
+/** 
+ * @file llsearchcombobox.h
+ * @brief LLSearchComboBox class definition
+ *
+ * $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_LLSEARCHCOMBOBOX_H
+#define LL_LLSEARCHCOMBOBOX_H
+
+#include "llcombobox.h"
+#include "llsearchhistory.h"
+
+/**
+ * Search control with text box for search queries and a drop down list
+ * with recent queries. Supports text auto-complete and filtering of drop down list
+ * according to typed text.
+ */
+class LLSearchComboBox : public LLComboBox
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLComboBox::Params>
+	{
+		Optional<LLButton::Params> search_button;
+		Optional<bool> dropdown_button_visible;
+
+		Params();
+	};
+
+	/**
+	 * Removes an entry from combo box, case insensitive
+	 */
+	BOOL remove(const std::string& name);
+
+	/**
+	 * Clears search history
+	 */
+	void clearHistory();
+
+	~LLSearchComboBox();
+
+protected:
+
+	LLSearchComboBox(const Params&p);
+	friend class LLUICtrlFactory;
+
+	/**
+	 * Handles typing in text box
+	 */
+	void onTextEntry(LLLineEditor* line_editor);
+
+	/**
+	 * Hides drop down list and focuses text box
+	 */
+	void hideList();
+
+	/**
+	 * Rebuilds search history, case insensitive
+	 * If filter is an empty string - whole history will be added to combo box
+	 * if filter is valid string - only matching entries will be added
+	 */
+	virtual void rebuildSearchHistory(const std::string& filter);
+
+	/**
+	 * Callback for prearrange event
+	 */
+	void onSearchPrearrange(const LLSD& data);
+
+	/**
+	 * Callback for text box or combo box commit
+	 */
+	void onSelectionCommit();
+
+	/**
+	 * Sets focus to text box
+	 */
+	void focusTextEntry();
+
+	LLButton* mSearchButton;
+};
+
+#endif //LL_LLSEARCHCOMBOBOX_H
diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d45a1efa0ea545ec21b83b9ba271a1b783bea798
--- /dev/null
+++ b/indra/newview/llsearchhistory.cpp
@@ -0,0 +1,154 @@
+/**
+ * @file llsearchhistory.cpp
+ * @brief Search history container 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 "llsearchhistory.h"
+
+#include "llfile.h"
+#include "llsdserialize.h"
+#include "llxmlnode.h"
+
+std::string LLSearchHistory::SEARCH_QUERY = "search_query";
+std::string LLSearchHistory::SEARCH_HISTORY_FILE_NAME = "search_history.txt";
+
+LLSearchHistory::LLSearchHistory()
+{
+
+}
+
+bool LLSearchHistory::load()
+{
+	// build filename for each user
+	std::string resolved_filename = getHistoryFilePath();
+	llifstream file(resolved_filename);
+	if (!file.is_open())
+	{
+		return false;
+	}
+
+	clearHistory();
+
+	// add each line in the file to the list
+	std::string line;
+	LLPointer<LLSDParser> parser = new LLSDNotationParser();
+	while (std::getline(file, line)) 
+	{
+		LLSD s_item;
+		std::istringstream iss(line);
+		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+		{
+			break;
+		}
+
+		mSearchHistory.push_back(s_item);
+	}
+
+	file.close();
+
+	return true;
+}
+
+bool LLSearchHistory::save()
+{
+	// build filename for each user
+	std::string resolved_filename = getHistoryFilePath();
+	// open a file for writing
+	llofstream file (resolved_filename);
+	if (!file.is_open())
+	{
+		return false;
+	}
+
+	search_history_list_t::const_iterator it = mSearchHistory.begin();
+	for (; mSearchHistory.end() != it; ++it)
+	{
+		file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl;
+	}
+
+	file.close();
+	return true;
+}
+
+std::string LLSearchHistory::getHistoryFilePath()
+{
+	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SEARCH_HISTORY_FILE_NAME);
+}
+
+void LLSearchHistory::addEntry(const std::string& search_query)
+{
+	if(search_query.empty())
+	{
+		return;
+	}
+
+	search_history_list_t::iterator it = 
+		find(mSearchHistory.begin(), mSearchHistory.end(), search_query);
+
+	if(mSearchHistory.end() != it)
+	{
+		mSearchHistory.erase(it);
+	}
+
+	LLSearchHistoryItem item(search_query);
+	mSearchHistory.push_front(item);
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator < (const LLSearchHistory::LLSearchHistoryItem& right)
+{
+	S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query);
+
+	return result < 0;
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator > (const LLSearchHistory::LLSearchHistoryItem& right)
+{
+	S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query);
+
+	return result > 0;
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator==(const LLSearchHistory::LLSearchHistoryItem& right)
+{
+	return 0 == LLStringUtil::compareInsensitive(search_query, right.search_query);
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator==(const std::string& right)
+{
+	return 0 == LLStringUtil::compareInsensitive(search_query, right);
+}
+
+LLSD LLSearchHistory::LLSearchHistoryItem::toLLSD() const
+{
+	LLSD ret;
+	ret[SEARCH_QUERY] = search_query;
+	return ret;
+}
diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h
new file mode 100644
index 0000000000000000000000000000000000000000..253ef21e9e182a50e0fccbd17adf4444a521a374
--- /dev/null
+++ b/indra/newview/llsearchhistory.h
@@ -0,0 +1,138 @@
+/** 
+ * @file llsearchhistory.h
+ * @brief Search history container definition
+ *
+ * $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_LLSEARCHHISTORY_H
+#define LL_LLSEARCHHISTORY_H
+
+#include "llsingleton.h"
+/**
+ * Search history container able to save and load history from file.
+ * History is stored in chronological order, most recent at the beginning.
+ */
+class LLSearchHistory : public LLSingleton<LLSearchHistory>
+{
+public:
+
+	// Forward declaration
+	class LLSearchHistoryItem;
+
+	// Search history container
+	typedef std::list<LLSearchHistoryItem>	search_history_list_t;
+
+	/**
+	 * Saves search history to file
+	 */
+	bool save();
+
+	/**
+	 * loads search history from file
+	 */
+	bool load();
+
+	/**
+	 * Returns search history list
+	 */
+	search_history_list_t& getSearchHistoryList() { return mSearchHistory; }
+
+	/**
+	 * Deletes all search history queries from list.
+	 */
+	void clearHistory() { mSearchHistory.clear(); }
+
+	/**
+	 * Adds unique entry to front of search history list, case insensitive
+	 * If entry is already in list, it will be deleted and added to front.
+	 */
+	void addEntry(const std::string& search_text);
+
+	LLSearchHistory();
+
+	/**
+	 * Class for storing data about single search request.
+	 */
+	class LLSearchHistoryItem
+	{
+	public:
+
+		LLSearchHistoryItem()
+		{}
+
+		LLSearchHistoryItem(const std::string& query)
+			: search_query(query)
+		{}
+
+		LLSearchHistoryItem(const LLSD& item)
+		{
+			if(item.has(SEARCH_QUERY))
+				search_query = item[SEARCH_QUERY].asString();
+		}
+
+		std::string search_query;
+
+		/**
+		 * Allows std::list sorting
+		 */
+		bool operator < (const LLSearchHistory::LLSearchHistoryItem& right);
+
+		/**
+		 * Allows std::list sorting
+		 */
+		bool operator > (const LLSearchHistory::LLSearchHistoryItem& right);
+
+		bool operator==(const LLSearchHistoryItem& right);
+
+		bool operator==(const std::string& right);
+
+		/**
+		 * Serializes search history item to LLSD
+		 */
+		LLSD toLLSD() const;
+	};
+
+protected:
+
+	/**
+	 * Returns path to search history file.
+	 */
+	std::string getHistoryFilePath();
+
+	static std::string SEARCH_HISTORY_FILE_NAME;
+	static std::string SEARCH_QUERY;
+
+private:
+
+	search_history_list_t mSearchHistory;
+};
+
+class LLSearchComboBox;
+
+#endif //LL_LLSEARCHHISTORY_H
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index afa8e5f072d09ebc9cb3f4bbb46b719766cce68f..381e63f020baf6f45c214d737f8da3044dafdc9d 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -241,6 +241,13 @@ LLSideTray::LLSideTray(Params& params)
 	    ,mMaxBarWidth(params.rect.width)
 {
 	mCollapsed=params.collapsed;
+
+
+	LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+
+	// 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));
 }
 
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6c0481feaa99efc245d0e3f2fa776f68914ec715..8fb0f201cb01d2bcaa73b61c2a9c0cd2b477387c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -899,6 +899,10 @@ bool idle_startup()
 
 	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
 	{
+		// Move the progress view in front of the UI immediately when login is performed
+		// this allows not to see main menu after Alt+Tab was pressed while login. EXT-744.
+		gViewerWindow->moveProgressViewToFront();
+
 		//reset the values that could have come in from a slurl
 		if (!gLoginHandler.getWebLoginKey().isNull())
 		{
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 2bbb5a2767853ea2e30fe8e5ccb3d4b80c7af5bf..7ddbf0a7444f95466920b8fd0b82e5bfbc7d8167 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -38,31 +38,34 @@
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 
+#include "llchiclet.h"
 //---------------------------------------------------------------------------------
-LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()),
+LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),
 													mChannel(NULL),
 													mScrollContainer(NULL),
 													mNotificationList(NULL)
 {
+	LLIMMgr::getInstance()->addSessionObserver(this);
+	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1));
 }
 
 //---------------------------------------------------------------------------------
 BOOL LLSysWellWindow::postBuild()
 {
 	mScrollContainer = getChild<LLScrollContainer>("notification_list_container");
+	mTwinListPanel = getChild<LLPanel>("twin_list_panel");
 	mNotificationList = getChild<LLScrollingPanelList>("notification_list");
+	mIMRowList = getChild<LLScrollingPanelList>("im_row_panel_list");
 
-	gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized
 	mScrollContainer->setBorderVisible(FALSE);
 
-	mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
-
-	return TRUE;
+	return LLDockableFloater::postBuild();
 }
 
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
 {
+	LLIMMgr::getInstance()->removeSessionObserver(this);
 }
 
 //---------------------------------------------------------------------------------
@@ -75,7 +78,6 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
 	LLSysWellItem* new_item = new LLSysWellItem(p);
 	mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item));
 	reshapeWindow();
-	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized
 
 	new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
 	new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
@@ -120,11 +122,6 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 		return;
 
 	reshapeWindow();
-	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized
-	// hide chiclet window if there are no items left
-	S32 items_left = mNotificationList->getPanelList().size();
-	if(items_left == 0)
-		setVisible(FALSE);
 }
 
 //---------------------------------------------------------------------------------
@@ -142,11 +139,20 @@ void LLSysWellWindow::onItemClose(LLSysWellItem* item)
 	removeItemByID(id);
 	if(mChannel)
 		mChannel->killToastByNotificationID(id);
+
+	// hide chiclet window if there are no items left
+	setVisible(!isWindowEmpty());
 }
 
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::toggleWindow()
 {
+	if (getDockControl() == NULL)
+	{
+		setDockControl(new LLDockControl(
+				LLBottomTray::getInstance()->getSysWell(), this,
+				getDockTongue(), LLDockControl::TOP, isDocked()));
+	}
 	setVisible(!getVisible());
 }
 
@@ -156,27 +162,26 @@ void LLSysWellWindow::setVisible(BOOL visible)
 	// on Show adjust position of SysWell chiclet's window
 	if(visible)
 	{
+		if (LLBottomTray::instanceExists())
+		{
+			LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE);
+		}
 		if(mChannel)
 			mChannel->removeAndStoreAllVisibleToasts();
-
-		adjustWindowPosition();	// *TODO: won't be necessary after docking is realized
 	}
-
+	else
+	{
+		if (LLBottomTray::instanceExists())
+		{
+			LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE);
+		}
+	}
 	if(mChannel)
 		mChannel->setShowToasts(!visible);
 
 	LLFloater::setVisible(visible);
 }
 
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::adjustWindowPosition()	// *TODO: won't be necessary after docking is realized
-{
-	const S32 WINDOW_MARGIN	= 5;
-
-	LLRect btm_rect = LLBottomTray::getInstance()->getRect();
-	LLRect this_rect = getRect();
-	setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN); 
-}
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::reshapeWindow()
 {
@@ -184,30 +189,205 @@ void LLSysWellWindow::reshapeWindow()
 	const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0);
 	const LLUICachedControl<S32> HEADER_SIZE("UIFloaterHeaderSize", 0);
 
-	// Get item list	
-	const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList();
+	LLRect notif_list_rect = mNotificationList->getRect();
+	LLRect im_list_rect = mIMRowList->getRect();
+	LLRect panel_rect = mTwinListPanel->getRect();
+
+	S32 notif_list_height = notif_list_rect.getHeight();
+	S32 im_list_height = im_list_rect.getHeight();
 
-	// Get height for a scrolling panel list
-	S32 list_height	= mNotificationList->getRect().getHeight();
+	S32 new_panel_height = notif_list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + im_list_height;
+	S32 new_window_height = new_panel_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE;
 
-	// Check that the floater doesn't exceed its parent view limits after reshape
-	S32 new_height = list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE;
+	U32 twinListWidth = 0;
 
-	if(new_height > MAX_WINDOW_HEIGHT)
+	if (new_window_height > MAX_WINDOW_HEIGHT)
 	{
-		reshape(MIN_WINDOW_WIDTH, MAX_WINDOW_HEIGHT, FALSE);
-		mNotificationList->reshape(MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE, list_height, TRUE);
+		twinListWidth = MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE;
+		new_window_height = MAX_WINDOW_HEIGHT;
 	}
 	else
 	{
-		reshape(MIN_WINDOW_WIDTH, new_height, FALSE);
-		mNotificationList->reshape(MIN_PANELLIST_WIDTH, list_height, TRUE);
+		twinListWidth = MIN_PANELLIST_WIDTH;
 	}
-	
+
+	reshape(MIN_WINDOW_WIDTH, new_window_height, FALSE);
+	mTwinListPanel->reshape(twinListWidth, new_panel_height, TRUE);
+	mNotificationList->reshape(twinListWidth, notif_list_height, TRUE);
+	mIMRowList->reshape(twinListWidth, im_list_height, TRUE);
+
+	// arrange panel and lists
+	// move panel
+	panel_rect.setLeftTopAndSize(1, new_panel_height, twinListWidth, new_panel_height);
+	mTwinListPanel->setRect(panel_rect);
+	// move notif list panel
+	notif_list_rect.setLeftTopAndSize(notif_list_rect.mLeft, new_panel_height, twinListWidth, notif_list_height);
+	mNotificationList->setRect(notif_list_rect);
+	// move IM list panel
+	im_list_rect.setLeftTopAndSize(im_list_rect.mLeft, notif_list_rect.mBottom - LLScrollingPanelList::GAP_BETWEEN_PANELS, twinListWidth, im_list_height);
+	mIMRowList->setRect(im_list_rect);
+
 	mNotificationList->updatePanels(TRUE);
+	mIMRowList->updatePanels(TRUE);
+}
+
+//---------------------------------------------------------------------------------
+LLSysWellWindow::RowPanel * LLSysWellWindow::findIMRow(const LLUUID& sessionId)
+{
+	RowPanel * res = NULL;
+	const LLScrollingPanelList::panel_list_t &list = mIMRowList->getPanelList();
+	if (!list.empty())
+	{
+		for (LLScrollingPanelList::panel_list_t::const_iterator iter = list.begin(); iter != list.end(); ++iter)
+		{
+			RowPanel *panel = static_cast<RowPanel*> (*iter);
+			if (panel->mChiclet->getSessionId() == sessionId)
+			{
+				res = panel;
+				break;
+			}
+		}
+	}
+	return res;
+}
+
+//---------------------------------------------------------------------------------
+LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId)
+{
+	LLChiclet* res = NULL;
+	RowPanel* panel = findIMRow(sessionId);
+	if (panel != NULL)
+	{
+		res = panel->mChiclet;
+	}
+
+	return res;
 }
 
 //---------------------------------------------------------------------------------
+void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
+		const std::string& name, const LLUUID& otherParticipantId)
+{
 
+	mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId));
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::delIMRow(const LLUUID& sessionId)
+{
+	RowPanel *panel = findIMRow(sessionId);
+	if (panel != NULL)
+	{
+		mIMRowList->removePanel(panel);
+	}
 
+	// hide chiclet window if there are no items left
+	setVisible(!isWindowEmpty());
+}
 
+//---------------------------------------------------------------------------------
+bool LLSysWellWindow::isWindowEmpty()
+{
+	if(mIMRowList->getPanelList().size() == 0 && LLBottomTray::getInstance()->getSysWell()->getCounter() == 0)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+//---------------------------------------------------------------------------------
+//virtual
+void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
+		const std::string& name, const LLUUID& otherParticipantId)
+{
+	if (findIMRow(sessionId) == NULL)
+	{
+		S32 chicletCounter = 0;
+		LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
+				sessionId, (LLIMModel::LLIMSession*) NULL);
+		if (session != NULL)
+		{
+			chicletCounter = session->mNumUnread;
+		}
+		addIMRow(sessionId, chicletCounter, name, otherParticipantId);
+		reshapeWindow();
+	}
+}
+
+//---------------------------------------------------------------------------------
+//virtual
+void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)
+{
+	delIMRow(sessionId);
+	reshapeWindow();
+	LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
+}
+
+//---------------------------------------------------------------------------------
+LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
+		S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
+		LLScrollingPanel(LLPanel::Params()), mParent(parent)
+{
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL);
+
+	mChiclet = getChild<LLIMChiclet>("chiclet");
+	mChiclet->setCounter(chicletCounter);
+	mChiclet->setSessionId(sessionId);
+	mChiclet->setIMSessionName(name);
+	mChiclet->setOtherParticipantId(otherParticipantId);
+
+	LLTextBox* contactName = getChild<LLTextBox>("contact_name");
+	contactName->setValue(name);
+
+	mCloseBtn = getChild<LLButton>("hide_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClose, this));
+}
+
+//---------------------------------------------------------------------------------
+LLSysWellWindow::RowPanel::~RowPanel()
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::RowPanel::onClose()
+{
+	mParent->mIMRowList->removePanel(this);
+	gIMMgr->removeSession(mChiclet->getSessionId());
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
+}
+
+//---------------------------------------------------------------------------------
+// virtual
+BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	// Pass the mouse down event to the chiclet (EXT-596).
+	if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
+		mChiclet->onMouseDown();
+
+	return LLPanel::handleMouseDown(x, y, mask);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify)
+{
+	S32 parent_width = getParent()->getRect().getWidth();
+	S32 panel_height = getRect().getHeight();
+
+	reshape(parent_width, panel_height, TRUE);
+}
+
+//---------------------------------------------------------------------------------
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 7a107af0d15c0c6d311ed4de4f2d36c0ac4f297c..ef0974b4284bfa88b5f318eebe870a59df4bd7ae 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -35,22 +35,27 @@
 
 #include "llsyswellitem.h"
 
-#include "llfloater.h"
+#include "lldockablefloater.h"
 #include "llbutton.h"
 #include "llscreenchannel.h"
 #include "llscrollcontainer.h"
+#include "llchiclet.h"
+#include "llimview.h"
 
 #include "boost/shared_ptr.hpp"
 
 
 
-class LLSysWellWindow : public LLFloater
+class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
 {
 public:
     LLSysWellWindow(const LLSD& key);
     ~LLSysWellWindow();
 	BOOL postBuild();
 
+	// other interface functions
+	bool isWindowEmpty();
+
 	// change attributes
 	void setChannel(LLNotificationsUI::LLScreenChannel*	channel) {mChannel = channel;}
 
@@ -75,15 +80,46 @@ class LLSysWellWindow : public LLFloater
 	static const S32 MIN_PANELLIST_WIDTH	= 318;
 
 private:
-
+	class RowPanel;
 	void reshapeWindow();
+	RowPanel * findIMRow(const LLUUID& sessionId);
+	LLChiclet * findIMChiclet(const LLUUID& sessionId);
+	void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
+	void delIMRow(const LLUUID& sessionId);
+	// LLIMSessionObserver observe triggers
+	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	virtual void sessionRemoved(const LLUUID& session_id);
 
 	// pointer to a corresponding channel's instance
 	LLNotificationsUI::LLScreenChannel*	mChannel;
-
-	LLUIImagePtr			mDockTongue;
+	LLPanel*				mTwinListPanel;
 	LLScrollContainer*		mScrollContainer;
+	LLScrollingPanelList*	mIMRowList;
 	LLScrollingPanelList*	mNotificationList;
+
+private:
+	/**
+	 * Scrolling row panel.
+	 */
+	class RowPanel: public LLScrollingPanel
+	{
+	public:
+		RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter,
+				const std::string& name, const LLUUID& otherParticipantId);
+		virtual ~RowPanel();
+		/*virtual*/
+		void updatePanel(BOOL allow_modify);
+		void onMouseEnter(S32 x, S32 y, MASK mask);
+		void onMouseLeave(S32 x, S32 y, MASK mask);
+		BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	private:
+		void onClose();
+	public:
+		LLIMChiclet* mChiclet;
+	private:
+		LLButton*	mCloseBtn;
+		const LLSysWellWindow* mParent;
+	};
 };
 
 #endif // LL_LLSYSWELLWINDOW_H
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index b31edf1e5dfd282c67652e63a829368c160d13e1..0bb5a727e0bf37dc16b87800c2b98e3a9a6eda4a 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -37,8 +37,11 @@
 #include "llsd.h"
 #include "llsdserialize.h"
 #include "lldir.h"
+#include "llteleporthistory.h"
+#include "llagent.h"
 
-static LLTeleportHistoryStorage tpstorage;
+// Max offset for two global positions to consider them as equal
+const F64 MAX_GLOBAL_POS_OFFSET = 5.0f;
 
 LLTeleportHistoryPersistentItem::LLTeleportHistoryPersistentItem(const LLSD& val)
 {
@@ -58,15 +61,42 @@ LLSD LLTeleportHistoryPersistentItem::toLLSD() const
 	return val;
 }
 
+struct LLSortItemsByDate
+{
+	bool operator()(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b)
+	{
+		return a.mDate < b.mDate;
+	}
+};
+
 LLTeleportHistoryStorage::LLTeleportHistoryStorage() :
 	mFilename("teleport_history.txt")
 {
+	LLTeleportHistory *th = LLTeleportHistory::getInstance();
+	if (th)
+		th->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryStorage::onTeleportHistoryChange, this));	
+
+	load();
 }
 
 LLTeleportHistoryStorage::~LLTeleportHistoryStorage()
 {
 }
 
+void LLTeleportHistoryStorage::onTeleportHistoryChange()
+{
+	LLTeleportHistory *th = LLTeleportHistory::getInstance();
+	if (!th)
+		return;
+
+	const LLTeleportHistoryItem &item = th->getItems()[th->getCurrentItemIndex()];
+
+	addItem(item.mTitle, item.mGlobalPos);
+	save();
+
+	mHistoryChangedSignal();
+}
+
 void LLTeleportHistoryStorage::purgeItems()
 {
 	mItems.clear();
@@ -74,12 +104,45 @@ void LLTeleportHistoryStorage::purgeItems()
 
 void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos)
 {
-	mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos));
+	addItem(title, global_pos, LLDate::now());
+}
+
+
+bool LLTeleportHistoryStorage::compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b)
+{
+	return a.mTitle == b.mTitle && (a.mGlobalPos - b.mGlobalPos).length() < MAX_GLOBAL_POS_OFFSET;
 }
 
 void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)
 {
-	mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos, date));
+
+	LLTeleportHistoryPersistentItem item(title, global_pos, date);
+
+	slurl_list_t::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
+							    boost::bind(&LLTeleportHistoryStorage::compareByTitleAndGlobalPos, this, _1, item));
+
+	// If there is such item already, remove it, since new item is more recent
+	if (item_iter != mItems.end())
+	{
+		mItems.erase(item_iter);
+	}
+
+	mItems.push_back(item);
+
+	// Check whether sorting is needed
+	if (mItems.size() > 1)
+	{
+		item_iter = mItems.end();
+
+		item_iter--;
+		item_iter--;
+
+		// If second to last item is more recent than last, then resort items
+		if (item_iter->mDate > item.mDate)
+		{
+			std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
+		}
+	}
 }
 
 void LLTeleportHistoryStorage::removeItem(S32 idx)
@@ -145,6 +208,8 @@ void LLTeleportHistoryStorage::load()
 	}
 
 	file.close();
+
+	std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
 }
 
 void LLTeleportHistoryStorage::dump() const
@@ -162,3 +227,30 @@ void LLTeleportHistoryStorage::dump() const
 	}
 }
 
+boost::signals2::connection LLTeleportHistoryStorage::setHistoryChangedCallback(history_callback_t cb)
+{
+	return mHistoryChangedSignal.connect(cb);
+}
+
+void LLTeleportHistoryStorage::goToItem(S32 idx)
+
+{
+	// Validate specified index.
+	if (idx < 0 || idx >= (S32)mItems.size())
+	{
+		llwarns << "Invalid teleport history index (" << idx << ") specified" << llendl;
+		dump();
+		return;
+	}
+	
+	if (idx == (S32)mItems.size() - 1)
+	{
+		llwarns << "Will not teleport to the same location." << llendl;
+		dump();
+		return;
+	}
+
+	// Attempt to teleport to the requested item.
+	gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
+}
+
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index fa836c0326729c07cf907de1b79b63e1faa29ab4..f67c4e2fb94cca7954f765168cc157da895607da 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -78,7 +78,10 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 
 public:
 
-	typedef std::vector<LLTeleportHistoryPersistentItem> item_list_list_t;
+	typedef std::vector<LLTeleportHistoryPersistentItem> slurl_list_t;
+
+	typedef boost::function<void()>		history_callback_t;
+	typedef boost::signals2::signal<void()>	history_signal_t;
 
 	LLTeleportHistoryStorage();
 	~LLTeleportHistoryStorage();
@@ -86,7 +89,7 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 	/**
 	 * @return history items.
 	 */
-	const item_list_list_t& getItems() const { return mItems; }
+	const slurl_list_t& getItems() const { return mItems; }
 	void			purgeItems();
 
 	void addItem(const std::string title, const LLVector3d& global_pos);
@@ -99,10 +102,34 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 
 	void dump() const;
 
+	/**
+	 * Set a callback to be called upon history changes.
+	 * 
+	 * Multiple callbacks can be set.
+	 */
+	boost::signals2::connection	setHistoryChangedCallback(history_callback_t cb);
+
+	/**
+	 * Go to specific item in the history.
+	 * 
+	 * The item is specified by its index (starting from 0).
+	 */
+	void					goToItem(S32 idx);
+
 private:
 
-	item_list_list_t	mItems;
-	std::string		mFilename;
+	void onTeleportHistoryChange();
+	bool compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b);
+
+	slurl_list_t	mItems;
+	std::string	mFilename;
+
+	/**
+	 * Signal emitted when the history gets changed.
+	 * 
+	 * Invokes callbacks set with setHistoryChangedCallback().
+	 */
+	history_signal_t		mHistoryChangedSignal;
 };
 
 #endif //LL_LLTELEPORTHISTORYSTORAGE_H
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 969f3fd1cb92944c271b5c7196051d7bc415c3d1..05e63a60c510fe3dafc2b402dde1640eab0af7ee 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -70,12 +70,16 @@ class LLToast : public LLFloater
 		bool				enable_hide_btn;
 		bool				is_modal;
 		bool				is_tip;
+		bool				force_show;
+		bool				force_store;
 
 		Params() :	can_fade(true),
 					can_be_stored(true),
 					is_modal(false),
 					is_tip(false),
 					enable_hide_btn(true),
+					force_show(false),
+					force_store(false),
 					panel(NULL),
 					timer_period(gSavedSettings.getS32("NotificationToastTime"))
 
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 6f26b4077cd0eb07474ccaa7dbae299782dd486a..6f373a74bdc7eaced59b543f63cbd1b10d14c80d 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -40,7 +40,7 @@
 #include "lliconctrl.h"
 #include "llnotify.h"
 #include "lltextbox.h"
-#include "lltexteditor.h"
+
 #include "lluiconstants.h"
 #include "llui.h"
 #include "llviewercontrol.h"
@@ -53,6 +53,8 @@
 #include "llfloaterinventory.h"
 #include "llinventorytype.h"
 
+const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 4;
+
 LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
 :	LLToastPanel(notification),
 	mInventoryOffer(NULL)
@@ -65,8 +67,6 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 		llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
 	}
 
-	static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor");
-
 	//group icon
 	LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
 	pGroupIcon->setValue(groupData.mInsigniaID);
@@ -78,23 +78,16 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 	LLTextBox* pTitleText = getChild<LLTextBox>("title");
 	pTitleText->setValue(from.str());
 
-	//message body
+	//message subject
 	const std::string& subject = payload["subject"].asString();
+	//message body
 	const std::string& message = payload["message"].asString();
 
-	LLTextEditor* pMessageText = getChild<LLTextEditor>("message");
-	pMessageText->setValue("");
-	pMessageText->setEnabled(FALSE);
 
-	LLStyle::Params date_style;
-	date_style.color = textColor;
-	date_style.font.name = "SANSSERIF";
-
-	LLStyle::Params header_style_params;
-	header_style_params.color = textColor;
-	header_style_params.font = LLFontGL::getFontSansSerifBig();
-	pMessageText->appendStyledText(subject + "\n",false,false,header_style_params);
+	LLTextBox* pSubjectText = getChild<LLTextBox>("subject");
+	pSubjectText->setValue(subject);
 
+	LLTextBox* pDateTimeText = getChild<LLTextBox>("datetime");
 	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
 							+LLTrans::getString("UTCTimeDay")+"] ["
 							+LLTrans::getString("UTCTimeMth")+"] ["
@@ -108,25 +101,38 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 	LLSD substitution;
 	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
 	LLStringUtil::format(timeStr, substitution);
-	LLStyle::Params date_style_params;
-	date_style_params.color = textColor;
-	date_style_params.font = LLFontGL::getFontMonospace();
-	pMessageText->appendStyledText(timeStr, false, false, date_style);
-	pMessageText->appendColoredText(std::string("\n\n") + message, false,
-			false, textColor);
+	pDateTimeText->setValue(timeStr);
+
+	LLTextBox* pMessageText = getChild<LLTextBox>("message");
+
+	//If message is empty let it be invisible and not take place at the panel
+	if(message.size() != 0)
+	{
+		pMessageText->setVisible(TRUE);
+		pMessageText->setValue(message);
+	}
+	else
+	{
+		pMessageText->setVisible(FALSE);
+	}
 
 	//attachment
 	BOOL hasInventory = payload["inventory_offer"].isDefined();
+
+	//attachment text
 	LLTextBox * pAttachLink = getChild<LLTextBox>("attachment");
+	//attachment icon
+	LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
+
+	//If attachment is empty let it be invisible and not take place at the panel
 	pAttachLink->setVisible(hasInventory);
+	pAttachIcon->setVisible(hasInventory);
 	if (hasInventory) {
 		pAttachLink->setValue(payload["inventory_name"]);
 		mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
 		childSetActionTextbox("attachment", boost::bind(
 				&LLToastGroupNotifyPanel::onClickAttachment, this));
 
-		//attachment icon
-		LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
 		LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType,
 												LLInventoryType::IT_TEXTURE,
 												0, FALSE);
@@ -137,8 +143,15 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 	LLButton* pOkBtn = getChild<LLButton>("btn_ok");
 	pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this)));
 	setDefaultBtn(pOkBtn);
-}
 
+	S32 maxLinesCount;
+	std::istringstream ss( getString("message_max_lines_count") );
+	if (!(ss >> maxLinesCount))
+	{
+		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+	}
+	snapToMessageHeight(pMessageText, maxLinesCount);
+}
 
 // virtual
 LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel()
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index ba98531251f69eb7d82b634f1c76fe09cef706d9..e3d0ef45cba131292dea9f7b7f5cd7f83f42011d 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -68,6 +68,8 @@ class LLToastGroupNotifyPanel
 private:
 	static bool isAttachmentOpenable(LLAssetType::EType);
 
+	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
+
 	LLButton* mSaveInventoryBtn;
 
 	LLUUID mGroupID;
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index e41181c9e1c109249c0fee5f59a3344c0dc32b26..913e46e05e06ec138966e5faae67910b8b9cc924 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -34,9 +34,7 @@
 #include "lltoastimpanel.h"
 #include "llimpanel.h"
 
-const S32 LLToastIMPanel::MAX_MESSAGE_HEIGHT	= 50;
-const S32 LLToastIMPanel::CAPTION_HEIGHT		= 30;
-const S32 LLToastIMPanel::TOP_PAD 				= 5;
+const S32 LLToastIMPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 6;
 
 //--------------------------------------------------------------------------
 LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notification),
@@ -60,7 +58,13 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif
 
 	mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
 
-	snapToMessageHeight();
+	S32 maxLinesCount;
+	std::istringstream ss( getString("message_max_lines_count") );
+	if (!(ss >> maxLinesCount))
+	{
+		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+	}
+	snapToMessageHeight(mMessage, maxLinesCount);
 }
 
 //--------------------------------------------------------------------------
@@ -68,22 +72,6 @@ LLToastIMPanel::~LLToastIMPanel()
 {
 }
 
-//--------------------------------------------------------------------------
-void LLToastIMPanel::snapToMessageHeight()
-{
-	S32 required_text_height = mMessage->getTextPixelHeight();
-	S32 text_height = llmin(required_text_height, MAX_MESSAGE_HEIGHT);
-	LLRect text_rect = mMessage->getRect();
-	LLRect btn_rect = mReplyBtn->getRect();
-
-
-	mMessage->reshape( text_rect.getWidth(), text_height, TRUE);
-	mMessage->setValue(mMessage->getText());
-
-	S32 panel_height = CAPTION_HEIGHT + text_height + btn_rect.getHeight() + TOP_PAD*5;
-	reshape( getRect().getWidth(), panel_height, TRUE);
-}
-
 //--------------------------------------------------------------------------
 void LLToastIMPanel::onClickReplyBtn()
 {
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 7f5d6eca1d702f701a6647e525ac10ae8662b338..11f489c12fc53fd7049d3a6f058998de133e72fc 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -59,12 +59,9 @@ class LLToastIMPanel: public LLToastPanel
 	virtual ~LLToastIMPanel();
 
 private:
-	static const S32 MAX_MESSAGE_HEIGHT;
-	static const S32 CAPTION_HEIGHT;
-	static const S32 TOP_PAD;
+	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
 
 	void onClickReplyBtn();
-	void snapToMessageHeight();
 
 	LLUUID				mSessionID;
 	LLAvatarIconCtrl*	mAvatar;
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 28052a33be7b4d6f72d4493beea5cb8da80ad05f..e884d89ce4b5c8b7bc0906cb7f4eab63a1e2de2b 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -49,5 +49,36 @@ std::string LLToastPanel::getTitle()
 	return mNotification->getMessage();
 }
 
+//snap to the message height if it is visible
+void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount)
+{
+	//Add message height if it is visible
+	if (message->getVisible())
+	{
+		S32 heightDelta = 0;
+		S32 maxTextHeight = (S32)(message->getFont()->getLineHeight() * maxLineCount);
+
+		LLRect messageRect = message->getRect();
+		S32 oldTextHeight = messageRect.getHeight();
+
+		//Reshape the toast to give the message max height.
+		//This needed to calculate lines count according to specified text
+		heightDelta = maxTextHeight - oldTextHeight;
+		reshape( getRect().getWidth(), getRect().getHeight() + heightDelta);
+		message->setValue(message->getText());
+
+		//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
+		//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
+		S32 requiredTextHeight = message->getTextPixelHeight();
+		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
 
+		//Calculate last delta height deducting previous heightDelta 
+		heightDelta = newTextHeight - oldTextHeight - heightDelta;
+
+		//reshape the panel with new height
+		reshape( getRect().getWidth(), getRect().getHeight() + heightDelta);
+		message->setValue(message->getText());
+	}
+
+}
 
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 2258eca273a102a8b5021d7ed9bc7cd6766e4a24..bc9888f4b48527d391c2917bbfa9a0d4961975e8 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -34,6 +34,7 @@
 #define LL_LLTOASTPANEL_H
 
 #include "llpanel.h"
+#include "lltextbox.h"
 #include "llnotifications.h"
 
 #include <string>
@@ -53,6 +54,7 @@ class LLToastPanel: public LLPanel {
 	virtual const LLUUID& getID() { return mNotification->id();}
 protected:
 	LLNotificationPtr mNotification;
+	void snapToMessageHeight(LLTextBox* message, S32 maxLineCount);
 };
 
 #endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index 5478e0005addc0d8fae3c34a89e3bc49adc8b274..c7c9f07504765b469351ae6170b6c91b1d211393 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -60,6 +60,7 @@
 #include "llui.h"
 #include "llviewermenu.h"
 #include "llfirstuse.h"
+#include "llpanelblockedlist.h"
 #include "llscrolllistctrl.h"
 #include "llscrolllistitem.h"
 #include "llscrolllistcell.h"
@@ -69,7 +70,6 @@
 #include "lltoolgrab.h"
 #include "llcombobox.h"
 #include "llfloaterchat.h"
-#include "llfloatermute.h"
 #include "llimpanel.h"
 #include "lllayoutstack.h"
 
@@ -250,41 +250,6 @@ void LLToolBar::refresh()
 	BOOL mouselook = gAgent.cameraMouselook();
 	setVisible(show && !mouselook);
 
-	BOOL sitting = FALSE;
-	if (gAgent.getAvatarObject())
-	{
-		sitting = gAgent.getAvatarObject()->isSitting();
-	}
-
-	if (!gAgent.canFly())
-	{
-		gSavedSettings.setBOOL("FlyBtnEnabled", gAgent.getFlying() ? true : false);
-		gSavedSettings.setBOOL("FlyBtnState", false);
-	}
-	else
-	{
-		gSavedSettings.setBOOL("FlyBtnEnabled", sitting ? false : true);
-	}
-
-	// Check to see if we're in build mode
-	bool build_enabled = LLToolMgr::getInstance()->canEdit();
-	if (build_enabled)
-	{
-		gSavedSettings.setBOOL("BuildBtnEnabled", true);
-		bool build_mode = LLToolMgr::getInstance()->inEdit();
-		// HACK: Not in mouselook and not just clicking on a scripted object
-		if (gAgent.cameraMouselook() || LLToolGrab::getInstance()->getHideBuildHighlight())
-	{
-		build_mode = FALSE;
-	}
-	gSavedSettings.setBOOL("BuildBtnState", build_mode);
-	}
-	else
-	{
-		gSavedSettings.setBOOL("BuildBtnEnabled", false);
-		gSavedSettings.setBOOL("BuildBtnState", false);
-	}
-
 	if (isInVisibleChain())
 	{
 		updateCommunicateList();
@@ -332,11 +297,8 @@ void LLToolBar::updateCommunicateList()
 	communicate_button->addSeparator(ADD_TOP);
 	communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP);
 	communicate_button->addSeparator(ADD_TOP);
-	LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
-	if(mute_instance)
-	{
-		communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP);
-	}
+	communicate_button->add(getString("Blocked List"), LLSD("mute list"), ADD_TOP);
+
 	std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
 
 	if (gIMMgr->getIMFloaterHandles().size() > 0)
@@ -414,7 +376,7 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data)
 	}
 	else if (selected_option.asString() == "mute list")
 	{
-		LLFloaterReg::showInstance("mute");
+		LLPanelBlockedList::showPanelAndSelect(LLUUID::null);
 	}
 	else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle
 	{
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index d52e0b4b800bf8e5beccd1117ebdc18311fd81cb..ded83debad8690eefdfd017c838bd8c98ddbecbd 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -317,7 +317,6 @@ bool LLToolMgr::inBuildMode()
 	// cameraMouselook() actually starts returning true.  Also, appearance edit
 	// sets build mode to true, so let's exclude that.
 	bool b=(inEdit() 
-			&& gSavedSettings.getBOOL("BuildBtnState")
 			&& !gAgent.cameraMouselook()
 			&& mCurrentToolset != gFaceEditToolset);
 	
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index b85dc30e7283e1b1983efcfeaf780efb509bfc69..c8f2e039039766bb60b85014cabe974f94ed09bc 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -78,7 +78,6 @@
 #include "llfloaterlandholdings.h"
 #include "llfloatermap.h"
 #include "llfloatermemleak.h"
-#include "llfloatermute.h"
 #include "llfloaternamedesc.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloateropenobject.h"
@@ -110,6 +109,7 @@
 #include "llmediaremotectrl.h"
 #include "llmoveview.h"
 #include "llnearbychat.h"
+#include "llpanelblockedlist.h"
 #include "llpreviewanim.h"
 #include "llpreviewgesture.h"
 #include "llpreviewnotecard.h"
@@ -177,8 +177,7 @@ void LLViewerFloaterReg::registerFloaters()
 	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>);
-	LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>);
-	LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI);
+	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
 	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
 	LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>);
 	
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 95ab40f9bf89cf33d5ec40cc3273047e88d2ac84..ec20af46a1853d585f175639433280a6e12f78bc 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -120,6 +120,41 @@ LLViewerInventoryItem::~LLViewerInventoryItem()
 {
 }
 
+BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const
+{
+	using std::string;
+	using std::stringstream;
+
+	const char separator = getSeparator();
+	const string::size_type separatorPos = mName.find(separator, 0);
+
+	BOOL result = FALSE;
+
+	if (separatorPos < string::npos)
+	{
+		if (sortField)
+		{
+			/*
+			 * The conversion from string to S32 is made this way instead of old plain
+			 * atoi() to ensure portability. If on some other platform S32 will not be
+			 * defined to be signed int, this conversion will still work because of
+			 * operators overloading, but atoi() may fail.
+			 */
+			stringstream ss(mName.substr(0, separatorPos));
+			ss >> *sortField;
+		}
+
+		if (displayName)
+		{
+			*displayName = mName.substr(separatorPos + 1, string::npos);
+		}
+
+		result = TRUE;
+	}
+
+	return result;
+}
+
 void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other)
 {
 	LLInventoryItem::copyItem(other);
@@ -1102,7 +1137,70 @@ const std::string& LLViewerInventoryItem::getName() const
 		return linked_category->getName();
 	}
 
-	return LLInventoryItem::getName();
+	return getDisplayName();
+}
+
+const std::string& LLViewerInventoryItem::getDisplayName() const
+{
+	std::string result;
+	BOOL hasSortField = extractSortFieldAndDisplayName(0, &result);
+
+	return mDisplayName = hasSortField ? result : LLInventoryItem::getName();
+}
+
+S32 LLViewerInventoryItem::getSortField() const
+{
+	S32 result;
+	BOOL hasSortField = extractSortFieldAndDisplayName(&result, 0);
+
+	return hasSortField ? result : -1;
+}
+
+void LLViewerInventoryItem::setSortField(S32 sortField)
+{
+	using std::string;
+
+	std::stringstream ss;
+	ss << sortField;
+
+	string newSortField = ss.str();
+
+	const char separator = getSeparator();
+	const string::size_type separatorPos = mName.find(separator, 0);
+
+	if (separatorPos < string::npos)
+	{
+		// the name of the LLViewerInventoryItem already consists of sort field and display name.
+		mName = newSortField + separator + mName.substr(separatorPos + 1, string::npos);
+	}
+	else
+	{
+		// there is no sort field in the name of LLViewerInventoryItem, we should add it
+		mName = newSortField + separator + mName;
+	}
+}
+
+void LLViewerInventoryItem::rename(const std::string& n)
+{
+	using std::string;
+
+	string new_name(n);
+	LLStringUtil::replaceNonstandardASCII(new_name, ' ');
+	LLStringUtil::replaceChar(new_name, '|', ' ');
+	LLStringUtil::trim(new_name);
+	LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
+
+	const char separator = getSeparator();
+	const string::size_type separatorPos = mName.find(separator, 0);
+
+	if (separatorPos < string::npos)
+	{
+		mName.replace(separatorPos + 1, string::npos, new_name);
+	}
+	else
+	{
+		mName = new_name;
+	}
 }
 
 const LLPermissions& LLViewerInventoryItem::getPermissions() const
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 0bfb37f7e83da69ed7dc8d1dde507c03c39ea60d..c4ff30bbfc43a9b893c5853df0bad082644648b2 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -55,11 +55,18 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	
 protected:
 	~LLViewerInventoryItem( void ); // ref counted
+	BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const;
+	static char getSeparator() { return '@'; }
+	mutable std::string mDisplayName;
 	
 public:
 	virtual LLAssetType::EType getType() const;
 	virtual const LLUUID& getAssetUUID() const;
 	virtual const std::string& getName() const;
+	virtual const std::string& getDisplayName() const;
+	virtual S32 getSortField() const;
+	virtual void setSortField(S32 sortField);
+	virtual void rename(const std::string& new_name);
 	virtual const LLPermissions& getPermissions() const;
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const std::string& getDescription() const;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8a5928f4e93432cfa29248a091072dcbff84cd4d..5536951ce6525777e86e26dc9bcaed13f85b89cb 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -113,7 +113,6 @@
 #include "llfloaterland.h"
 #include "llfloaterlandholdings.h"
 #include "llfloatermap.h"
-#include "llfloatermute.h"
 #include "llfloateropenobject.h"
 #include "llfloaterperms.h"
 #include "llfloaterpostprocess.h"
@@ -147,6 +146,7 @@
 #include "llfloaterinventory.h"
 #include "llkeyboard.h"
 #include "llpanellogin.h"
+#include "llpanelblockedlist.h"
 #include "llmenucommands.h"
 #include "llmenugl.h"
 #include "llmimetypes.h"
@@ -2896,7 +2896,7 @@ class LLObjectMute : public view_listener_t
 		else
 		{
 			LLMuteList::getInstance()->add(mute);
-			LLFloaterReg::showInstance("mute");
+			LLPanelBlockedList::showPanelAndSelect(mute.mID);
 		}
 		
 		return true;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 111cdf7c12093882c5366a321cfa6509aa817fe7..2a2b0958339f64edd7fa5d6dd518c3e4cff807eb 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1,4 +1,3 @@
-
 /** 
  * @file llviewermessage.cpp
  * @brief Dumping ground for viewer-side message system callbacks.
@@ -83,7 +82,6 @@
 #include "llfloaterregioninfo.h"
 #include "llfloaterlandholdings.h"
 #include "llurldispatcher.h"
-#include "llfloatermute.h"
 #include "llfloaterpostcard.h"
 #include "llfloaterpreference.h"
 #include "llfollowcam.h"
@@ -138,6 +136,9 @@
 #include "llkeythrottle.h"
 #include "llgroupactions.h"
 #include "llagentui.h"
+#include "llsidetray.h"
+#include "llpanelblockedlist.h"
+#include "llpanelplaceinfo.h"
 
 #include <boost/tokenizer.hpp>
 #include <boost/algorithm/string/split.hpp>
@@ -1000,9 +1001,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 	LLMute mute(blocked_id, from_name, type);
 	if (LLMuteList::getInstance()->add(mute))
 	{
-		LLFloaterReg::showInstance("mute");
-		LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
-		if(mute_instance) mute_instance->selectMute(blocked_id);
+		LLPanelBlockedList::showPanelAndSelect(blocked_id);
 	}
 
 	// purge the message queue of any previously queued inventory offers from the same source.
@@ -1472,6 +1471,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
 	EInstantMessage dialog = (EInstantMessage)d;
 
+    // make sure that we don't have an empty or all-whitespace name
+	LLStringUtil::trim(name);
+	if (name.empty())
+	{
+        name = LLTrans::getString("Unnamed");
+	}
+
 	BOOL is_busy = gAgent.getBusy();
 	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
 	BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
@@ -2397,6 +2403,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		// Look for IRC-style emotes
 		if (ircstyle)
 		{
+			// set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656
+			chat.mChatStyle = CHAT_STYLE_IRC;
+
 			// Do nothing, ircstyle is fixed above for chat bubbles
 		}
 		else
@@ -5565,6 +5574,12 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
 	LLPanelLandCovenant::updateEstateName(estate_name);
 	LLFloaterBuyLand::updateEstateName(estate_name);
 
+	LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");
+	if (panel)
+	{
+		panel->updateEstateName(estate_name);
+	}
+
 	// standard message, not from system
 	std::string last_modified;
 	if (covenant_timestamp == 0)
@@ -5622,6 +5637,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
 		LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
 		LLPanelLandCovenant::updateCovenantText(covenant_text);
 		LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id);
+		panel->updateCovenantText(covenant_text);
 	}
 }
 
@@ -5642,6 +5658,12 @@ void callbackCacheEstateOwnerName(const LLUUID& id,
 	LLPanelEstateCovenant::updateEstateOwnerName(name);
 	LLPanelLandCovenant::updateEstateOwnerName(name);
 	LLFloaterBuyLand::updateEstateOwnerName(name);
+
+	LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");
+	if (panel)
+	{
+		panel->updateEstateOwnerName(name);
+	}
 }
 
 void onCovenantLoadComplete(LLVFS *vfs,
@@ -5709,6 +5731,12 @@ void onCovenantLoadComplete(LLVFS *vfs,
 	LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
 	LLPanelLandCovenant::updateCovenantText(covenant_text);
 	LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
+
+	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD()));
+	if (panel)
+	{
+		panel->updateCovenantText(covenant_text);
+	}
 }
 
 
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index de01e7980390de1b784dd534287f28208f804419..5bb0c9a120ad957b3b5874384742f49d4c26ded1 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -814,38 +814,18 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
 
 BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
-
-	// *TODO: Add right click menus for SLURLs
-// 	if(! handled)
-// 	{
-// 		const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
-// 		if( cur_segment )
-// 		{
-// 			if(cur_segment->getStyle()->isLink())
-// 			{
-// 				handled = TRUE;
-// 				mHTML = cur_segment->getStyle()->getLinkHREF();
-// 			}
-// 		}
-// 	}
-// 	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-// 	if(handled && menu && mParseHTML && mHTML.length() > 0)
-// 	{
-// 		menu->setVisible(TRUE);
-// 		menu->arrange();
-// 		menu->updateParent(LLMenuGL::sMenuContainer);
-// 		LLMenuGL::showPopup(this, menu, x, y);
-// 		mHTML = "";
-// 	}
-// 	else
-// 	{
-// 		if(menu && menu->getVisible())
-// 		{
-// 			menu->setVisible(FALSE);
-// 		}
-// 	}
-	return handled;
+	// pop up a context menu for any Url under the cursor
+	if (handleRightMouseDownOverUrl(this, x, y))
+	{
+		return TRUE;
+	}
+
+	if (childrenHandleRightMouseDown(x, y, mask) != NULL)
+	{
+		return TRUE;
+	}
+
+	return FALSE;
 }
 
 BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -1087,6 +1067,7 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)
 void LLViewerTextEditor::onValueChange(S32 start, S32 end)
 {
 	updateSegments();
+	updateLinkSegments();
 	findEmbeddedItemSegments(start, end);
 }
 
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index 9567bfbc48e1fb0d755c5d2409a7a3c5079d123d..2dfea4a5893d076a0ff521bbbe94887809c25754 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -35,7 +35,6 @@
 
 #include "lltexteditor.h"
 
-
 //
 // Classes
 //
@@ -137,9 +136,6 @@ class LLViewerTextEditor : public LLTextEditor
 
 	LLPointer<class LLEmbeddedNotecardOpener> mInventoryCallback;
 
-	// *TODO: Add right click menus for SLURLs
-	//LLViewHandle mPopupMenuHandle;
-
 	//
 	// Inner classes
 	//
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 461f7fc1c70fa80363d002aaaec9958e2ccdf3e4..241c6fd51152df77b622d916cb065ea4db32c653 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1596,8 +1596,6 @@ void LLViewerWindow::initWorldUI()
 	gFloaterView->setRect(floater_view_rect);
 	gNotifyBoxView->setRect(notify_view_rect);
 
-	// *Note: this is where gFloaterMute used to be initialized.
-
 	LLWorldMapView::initClass();
 	
 	// Force gFloaterWorldMap to initialize
@@ -1636,6 +1634,11 @@ void LLViewerWindow::initWorldUI()
 		navbar->showFavoritesPanel(FALSE);
 	}
 
+	if (!gSavedSettings.getBOOL("ShowCameraAndMoveControls"))
+	{
+		LLBottomTray::getInstance()->showCameraAndMoveControls(FALSE);
+	}
+
 	getRootView()->addChild(gStatusBar);
 	getRootView()->addChild(navbar);
 
@@ -1668,6 +1671,9 @@ void LLViewerWindow::initWorldUI()
 		// put behind everything else in the UI
 		getRootView()->addChildInBack(gHUDView);
 	}
+
+	// this allows not to see UI elements created while UI initializing after Alt+Tab was pressed during login. EXT-744.
+	moveProgressViewToFront();
 }
 
 // Destroy the UI
@@ -2870,7 +2876,7 @@ void LLViewerWindow::updateLayout()
 		{
 			gFloaterTools->setVisible(FALSE);
 		}
-		gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
+		//gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
 	}
 
 	// Always update console
@@ -4417,8 +4423,7 @@ void LLViewerWindow::moveProgressViewToFront()
 {
 	if( mProgressView && mRootView )
 	{
-		mRootView->removeChild( mProgressView );
-		mRootView->addChild( mProgressView );
+		mRootView->sendChildToFront(mProgressView);
 	}
 }
 
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 300a5db7c390960fe11c491304c9452dfebbbc46..3204c2d264208624c1c6b8fb53fa28b3901e5ec0 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -67,6 +67,7 @@ void LLWeb::initClass()
 	LLAlertDialog::setURLLoader(&sAlertURLLoader);
 }
 
+
 // static
 void LLWeb::loadURL(const std::string& url)
 {
@@ -76,11 +77,18 @@ void LLWeb::loadURL(const std::string& url)
 	}
 	else
 	{
-		LLFloaterReg::showInstance("media_browser",url);
+		loadURLInternal(url);
 	}
 }
 
 
+// static
+void LLWeb::loadURLInternal(const std::string &url)
+{
+	LLFloaterReg::showInstance("media_browser", url);
+}
+
+
 // static
 void LLWeb::loadURLExternal(const std::string& url)
 {
diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h
index 71cc236621a9225d163ebeaad1ad55544a068878..96a53db2ca053cd136f5c4ea82d8179df9d0f1e1 100644
--- a/indra/newview/llweb.h
+++ b/indra/newview/llweb.h
@@ -36,23 +36,29 @@
 
 #include <string>
 
+///
+/// The LLWeb class provides various static methods to display the
+/// contents of a Url in a web browser. Variations are provided to 
+/// let you specifically use the Second Life internal browser, the
+/// operating system's default browser, or to respect the user's
+/// setting for which of these two they prefer to use with SL.
+///
 class LLWeb
 {
 public:
 	static void initClass();
 	
-	// Loads unescaped url in either internal web browser or external
-	// browser, depending on user settings.
+	/// Load the given url in the user's preferred web browser
 	static void loadURL(const std::string& url);
-	
+	/// Load the given url in the user's preferred web browser	
 	static void loadURL(const char* url) { loadURL( ll_safe_string(url) ); }
-
-	// Loads unescaped url in external browser.
+	/// Load the given url in the Second Life internal web browser
+	static void loadURLInternal(const std::string &url);
+	/// Load the given url in the operating system's web browser
 	static void loadURLExternal(const std::string& url);
 
-	// Returns escaped (eg, " " to "%20") url
+	// Returns escaped url (eg, " " to "%20") - used by all loadURL methods
 	static std::string escapeURL(const std::string& url);
-
 };
 
 #endif
diff --git a/indra/newview/skins/default/textures/places_rating_adult.tga b/indra/newview/skins/default/textures/places_rating_adult.tga
new file mode 100644
index 0000000000000000000000000000000000000000..c344fb1e78887afe2b20ac4830ffb057772416cd
Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_adult.tga differ
diff --git a/indra/newview/skins/default/textures/places_rating_mature.tga b/indra/newview/skins/default/textures/places_rating_mature.tga
new file mode 100644
index 0000000000000000000000000000000000000000..61c879bc923c7d1ee625a3995012a3ddecca363d
Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_mature.tga differ
diff --git a/indra/newview/skins/default/textures/places_rating_pg.tga b/indra/newview/skins/default/textures/places_rating_pg.tga
new file mode 100644
index 0000000000000000000000000000000000000000..7805dbce60eb7c58bb99826157ed222813c27419
Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_pg.tga differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 0bd5f114ed92d86ed5cbfb01ebbf2d550822bd2d..e32ea0944ecb5a25b9667734990ba82b2736dc29 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -93,6 +93,7 @@
   <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false"/>
 
   <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" />
+  <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" />
 
   <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
 
diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml
index 38c6d44fdfe8883ba1b882c99beca8ec2be7354b..0af4e1db541a04f5fe10932f43edf4a86e051e01 100644
--- a/indra/newview/skins/default/xui/en/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/en/floater_activeim.xml
@@ -5,7 +5,7 @@
 	top="26"
 	left="0"
 	height="22"
-	width="350"
+	width="320"
 	follows="right|bottom"
 	background_visible="true"
 	can_close="true"
@@ -18,13 +18,14 @@
 		layout="topleft"
 		top="20"
 		left="1"
-		width="349"
+		width="320"
 		height="2"
 		name="panel_list_container">
 		<scrolling_panel_list
 			follows="left|right"
 			layout="topleft"
+      left="1"      
 			name="chiclet_row_panel_list"
-			width="335"/>
+			width="318"/>
 	</scroll_container>
 </floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index afc72a78a9c8995ea544ebf3447365531fc6525b..28b8139bfdb75a1e50ab86a98cbc7bbb6ac8aabe 100644
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -7,6 +7,7 @@
  min_width="467"
  name="floater_about"
  save_rect="true"
+ single_instance="true"
  title="Media Browser"
  width="820">
     <floater.string
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index 90711e3accff6012e885841782d9ab3b0d49b39d..0f6504c8751949484f104cfe2c9266aa326a3b9e 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -76,7 +76,7 @@
      height="40"
      layout="topleft"
      left_delta="84"
-     name="desc"
+     name="desc2"
      top_delta="-4"
      width="180" />
     
@@ -116,17 +116,17 @@
     <panel
      class="floater_snapshot_capture"
      filename="floater_snapshot_Info.xml"
-     name="snapshot_capture_tab"/> 
+     name="snapshot_capture_panel"/> 
     </accordion_tab>
     <accordion_tab
      min_height="100"
      title="Permissions"
-     name="snapshot_capture_tab"
+     name="snapshot_capture_tab2"
      can_resize="false">
     <panel
      class="floater_snapshot_capture"
      filename="floater_snapshot_Permissions.xml"
-     name="snapshot_capture_tab"/> 
+     name="snapshot_capture_panel2"/> 
     </accordion_tab>
     </accordion>
     <!--check_box
@@ -164,7 +164,7 @@
      label="Cancel (not working)"
      layout="topleft"
      left_pad="5"
-     name="save_btn"
+     name="cancel_btn"
      top_delta="0"
      width="80" />   
 
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index fcbc27a5f9fe4d954e4c5b98f7278d9634a1d701..0da1e4298628a2bd7dd93777963eb15b288daed4 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- height="590"
+ height="600"
  layout="topleft"
  name="floater_report_abuse"
  title="Report Abuse"
- width="390">
+ width="305">
     <floater.string
      name="Screenshot">
         Screenshot
@@ -15,27 +15,28 @@
      follows="left|top"
      height="114"
      layout="topleft"
-     left="238"
+     left="10"
      name="screenshot"
-     top="36"
+     top="25"
      width="134" />
     <check_box
      height="16"
      label="Include screenshot"
      layout="topleft"
-     left="13"
+     left_pad="10"
      name="screen_check"
-     top="134"
+     top="110"
      width="116" />
     <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
-     left_delta="3"
+     left="10"
      name="reporter_title"
-     top_delta="-102"
+     top_pad="12"
      width="50">
         Reporter:
     </text>
@@ -48,7 +49,7 @@
      left_pad="12"
      name="reporter_field"
      top_delta="0"
-     width="150">
+     width="193">
         Loremipsum Dolorsitamut
     </text>
     <text
@@ -56,10 +57,11 @@
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
-     left="16"
+     left="10"
      name="sim_title"
-     top="48"
+     top_pad="5"
      width="60">
         Region:
     </text>
@@ -72,7 +74,7 @@
      left_pad="2"
      name="sim_field"
      top_delta="0"
-     width="120">
+     width="193">
         Region Name
     </text>
     <text
@@ -80,10 +82,11 @@
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
-     left="16"
+     left="10"
      name="pos_title"
-     top="64"
+     top_pad="5"
      width="50">
         Position:
     </text>
@@ -96,18 +99,18 @@
      left_pad="12"
      name="pos_field"
      top_delta="0"
-     width="120">
+     width="193">
         {128.1, 128.1, 15.4}
     </text>
-    <text
+ <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
      layout="topleft"
-     left="16"
+     left="10"
      name="select_object_label"
-     top="82"
+     top_pad="5"
      width="220">
         Click the button then the object:
     </text>
@@ -118,15 +121,16 @@
      name="pick_btn"
      picture_style="true"
      tool_tip="Object Picker - Identify an object as the subject of this report"
-     top_delta="14"
+     top_pad="0"
      width="32" />
     <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
-     left_pad="5"
+     left="48"
      name="object_name_label"
      top_delta="0"
      width="60">
@@ -141,7 +145,7 @@
      left_pad="6"
      name="object_name"
      top_delta="0"
-     width="109">
+     width="157">
         Consetetur Sadipscing
     </text>
     <text
@@ -149,10 +153,11 @@
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
-     left="53"
+     left="48"
      name="owner_name_label"
-     top="112"
+     top_pad="5"
      width="60">
         Owner:
     </text>
@@ -165,17 +170,17 @@
      left_pad="6"
      name="owner_name"
      top_delta="0"
-     width="109">
+     width="157">
         Hendrerit Vulputate
-    </text>
+    </text> 
     <combo_box
      height="20"
      layout="topleft"
-     left="16"
+     left="10"
      name="category_combo"
      tool_tip="Category -- select the category that best describes this report"
-     top="156"
-     width="356">
+     top_pad="10"
+     width="265">
         <combo_box.item
          label="Select category"
          name="Select_category"
@@ -338,156 +343,161 @@
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
      left_delta="0"
      name="abuser_name_title"
-     top_pad="10"
-     width="180">
+     top_pad="12"
+     width="265">
         Abuser name:
     </text>
     <line_editor
      border_style="line"
      border_thickness="1"
      follows="left|top"
-     height="16"
+     height="20"
      layout="topleft"
      left_delta="0"
      max_length="32"
      name="abuser_name_edit"
      top_pad="2"
-     width="180" />
+     width="170" />
     <button
      height="20"
-     label="Choose Resident"
+     font="SansSerifSmall"
+     label="Choose"
      layout="topleft"
-     left_pad="10"
+     left_pad="5"
      name="select_abuser"
      tool_tip="Select the name of the abuser from a list"
-     top_delta="-2"
-     width="160" />
+     top_delta="0"
+     width="90" />
     <check_box
-     height="16"
+     height="20"
      label="Don&apos;t know abuser&apos;s name"
      layout="topleft"
-     left="13"
+     left="10"
      name="omit_abuser_name"
      tool_tip="Check this if you are unable to provide the abuser&apos;s name"
-     top="224"
+     top_pad="2"
      visible="false"
-     width="116" />
+     width="250" />
     <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
      left_delta="3"
      name="abuser_name_title2"
-     top_pad="8"
-     width="180">
+     top_pad="10"
+     width="265">
         Location of Abuse:
     </text>
     <line_editor
      border_style="line"
      border_thickness="1"
      follows="left|top"
-     height="16"
+     height="20"
      layout="topleft"
-     left_delta="0"
+     left="10"
      max_length="256"
      name="abuse_location_edit"
      top_pad="2"
-     width="356" />
+     width="265" />
     <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
      left_delta="0"
      name="sum_title"
-     top_pad="8"
-     width="180">
+     top_pad="10"
+     width="265">
         Summary:
     </text>
     <line_editor
      border_style="line"
      border_thickness="1"
      follows="left|top"
-     height="16"
+     height="20"
      layout="topleft"
      left_delta="0"
      max_length="64"
      name="summary_edit"
      top_pad="2"
-     width="356" />
+     width="265" />
     <text
      type="string"
      length="1"
      follows="left|top"
      height="16"
+     font.style="BOLD"
      layout="topleft"
      left_delta="0"
      name="dscr_title"
-     top_pad="8"
-     width="180">
+     top_pad="10"
+     width="50">
         Details:
     </text>
     <text
      type="string"
      length="1"
      follows="left|top"
-     height="48"
+     height="16"
      layout="topleft"
-     left_delta="54"
+     left_pad="5"
      name="bug_aviso"
      top_delta="0"
-     width="308">
-        Please be specific about the date, location, nature of
-abuse, relevant chat/IM text, and select the object
-if possible.
+     width="200">
+        Please be as specific as possible.
     </text>
     <text_editor
      follows="left|top"
-     height="146"
+     height="50"
      layout="topleft"
-     left="16"
+     left="10"
      max_length="800"
      mouse_opaque="false"
      name="details_edit"
-     top="386"
-     width="356"
+     top_pad="2"
+     width="265"
      word_wrap="true" />
     <text
      type="string"
      length="1"
      follows="left|top"
-     height="16"
+     height="50"
      layout="topleft"
      left_delta="0"
+     font.style="BOLD"
      name="incomplete_title"
      top_pad="8"
-     width="342">
+     word_wrap="true"
+     width="265">
         Note: Incomplete reports will not be investigated.
     </text>
     <button
-     bottom="580"
+     bottom="590"
      follows="right|bottom"
      height="20"
      label="Cancel"
      label_selected="Cancel"
      layout="topleft"
      name="cancel_btn"
-     right="373"
-     width="150" />
+     right="275"
+     width="130" />
     <button
-     bottom="580"
+     bottom="590"
      follows="right|bottom"
      height="20"
      label="Report Abuse"
      label_selected="Report Abuse"
      layout="topleft"
      name="send_btn"
-     right="217"
-     width="150" />
+     right="140"
+     width="130" />
 </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 46c8960fbd59565ae0257648cc6eb6c2228647a8..d76ea398d516df358733ed49c25766041840d353 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -4,16 +4,16 @@
  background_visible="true" 
  bevel_style="in"
  bg_alpha_color="0.0 0.0 0.0 0.0"
- height="30"
  left="0"
  top="0" 
  follows="right|bottom"
  layout="topleft"
  name="notification_chiclet"
  save_rect="true"
- title="NOTIFICATIONS"
+ title="NOTIFICATIONS" 
  width="320"
  min_width="320"
+ height="60"
  can_minimize="false"
  can_tear_off="false"
  can_resize="false"
@@ -21,20 +21,36 @@
  can_close="false"
  can_dock="true"
 >
-  <scroll_container
-   follows="top|bottom"
-   layout="topleft"
-   name="notification_list_container"
-   left="0"
-   top="18"
-   width="320"
-   height="12">
-    <scrolling_panel_list
-     layout="topleft"
-     name="notification_list"
-     left="1"
-     top="0"
-     height="10"
-     width="318" />
-  </scroll_container>
+	<scroll_container
+	follows="top|bottom"
+	layout="topleft"
+	name="notification_list_container"
+	left="0"
+	top="18"
+	width="320"
+	height="42">
+	<panel
+		layout="topleft"
+		name="twin_list_panel"
+		left="1"
+		top="0"
+		width="318"
+    height="32"
+    bg_alpha_color="1.0 1.0 1.0 1.0">
+		<scrolling_panel_list
+			layout="topleft"
+			name="notification_list"
+			left="1"
+			top="0"
+			height="0"
+			width="318"/>
+		<scrolling_panel_list
+			layout="topleft"
+			name="im_row_panel_list"
+			left="1"
+			top="2"
+			height="0"
+			width="318"/>
+	</panel>
+</scroll_container>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 51e4d15e5d0c561b211bb7650c9e8df61fc70d42..a126a932df1e6ca840fec01ca56c3be790246958 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1003,12 +1003,15 @@
             name="sale type"
             intial_value="2">
         <combo_item
+           name="Copy"
            label="Copy" 
            value="2" />
         <combo_item
+           name="Contents"
            label="Contents"  
            value="3" />
         <combo_item
+           name="Original"
            label="Original" 
            value="1" />
       </combo_box>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
index bb5a4e51f7e10570a522c789ceef34308d07cdd1..6ef1eb9513f87fe432f733c8691a937ee025fdc1 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
@@ -15,4 +15,8 @@
   <menu_item_call name="organize_offline" label="Organize Offline Friends">
     <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="organize_offline" />
   </menu_item_call>
+  <menu_item_separator layout="topleft" />
+  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+    <menu_item_call.on_click function="SideTray.ShowPanel" parameter="panel_block_list_sidetray" />
+  </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
index 8c2c5e8c9e436d11d5023f6f0047c6ddc20364e1..2b0f029016b053bd2cbfd0fa316d76d9155309e2 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
@@ -15,4 +15,8 @@
   <menu_item_call name="view_icons" label="View People Icons">
     <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="view_icons" />
   </menu_item_call>
+  <menu_item_separator layout="topleft" />
+  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+    <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" />
+  </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
index 00cf443cc62557cb6a9fdd9eb3424699eaa4474d..88b0528e53998f0cdb8d698611c52a096b680145 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
@@ -12,4 +12,8 @@
   <menu_item_call name="view_icons" label="View People Icons">
     <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="view_icons" />
   </menu_item_call>
+  <menu_item_separator layout="topleft" />
+  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+    <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" />
+  </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
new file mode 100644
index 0000000000000000000000000000000000000000..463a9fccb6581280e85f398d16cc119aefbf1b9c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Show Resident Profile"
+     layout="topleft"
+     name="show_agent">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy Name To Clipboard"
+     layout="topleft"
+     name="url_copy_label">
+        <menu_item_call.on_click
+         function="Url.CopyLabel" />
+    </menu_item_call>
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_group.xml b/indra/newview/skins/default/xui/en/menu_url_group.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cec0aa421e4ea93f7e481185dd8270695a454db6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_group.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Show Group Information"
+     layout="topleft"
+     name="show_group">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy Group To Clipboard"
+     layout="topleft"
+     name="url_copy_label">
+        <menu_item_call.on_click
+         function="Url.CopyLabel" />
+    </menu_item_call>
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_http.xml b/indra/newview/skins/default/xui/en/menu_url_http.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2503b4a2a377d4e7e1c66e90ee245300ad3ca757
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_http.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Open Web Page"
+     layout="topleft"
+     name="url_open">
+        <menu_item_call.on_click
+         function="Url.Open" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Open in Internal Browser"
+     layout="topleft"
+     name="url_open_internal">
+        <menu_item_call.on_click
+         function="Url.OpenInternal" />
+    </menu_item_call>
+    <menu_item_call
+     label="Open in External Browser"
+     layout="topleft"
+     name="url_open_external">
+        <menu_item_call.on_click
+         function="Url.OpenExternal" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy URL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7d09403b15818518d89eef0e470e3dfe3bfb1ff2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Show Object Information"
+     layout="topleft"
+     name="show_object">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Teleport to Object Location"
+     layout="topleft"
+     name="teleport_to_object">
+        <menu_item_call.on_click
+         function="Url.Teleport" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy Object Name To Clipboard"
+     layout="topleft"
+     name="url_copy_label">
+        <menu_item_call.on_click
+         function="Url.CopyLabel" />
+    </menu_item_call>
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bbd63c6d8c090deef7ca1cb4f777179cb963979a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Show Parcel Information"
+     layout="topleft"
+     name="show_parcel">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_slapp.xml b/indra/newview/skins/default/xui/en/menu_url_slapp.xml
new file mode 100644
index 0000000000000000000000000000000000000000..19df721b2bac631d120cfed4defc2ec5fdef7b15
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_slapp.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Run This Command"
+     layout="topleft"
+     name="run_slapp">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_slurl.xml b/indra/newview/skins/default/xui/en/menu_url_slurl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0e9525fa4b6f7847c38eaa01a3c3a5c80dd0dad8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_slurl.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Show Place Information"
+     layout="topleft"
+     name="show_place">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Teleport to Location"
+     layout="topleft"
+     name="teleport_to_location">
+        <menu_item_call.on_click
+         function="Url.Teleport" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_teleport.xml b/indra/newview/skins/default/xui/en/menu_url_teleport.xml
new file mode 100644
index 0000000000000000000000000000000000000000..22cc035e49d6a305f56e36b36400c9a22070c761
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_teleport.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+    <menu_item_call
+     label="Teleport To This Location"
+     layout="topleft"
+     name="teleport">
+        <menu_item_call.on_click
+         function="Url.Execute" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Copy SLURL To Clipboard"
+     layout="topleft"
+     name="url_copy">
+        <menu_item_call.on_click
+         function="Url.CopyUrl" />
+    </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 ef9e22d9085dbf4b5806139ac4b358afe6d7c3a0..6bc12368b7e112093f69ccc508bbd72aae336638 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -229,7 +229,7 @@
              function="Floater.Toggle"
              parameter="communicate" />
         </menu_item_check>
-		<menu_item_call
+        <menu_item_call
          label="(Temp) Media Remote Ctrl"
          layout="topleft"
          name="Preferences"
@@ -284,6 +284,44 @@
              function="Floater.Show"
              parameter="region_info" />
         </menu_item_call>
+        <menu
+           create_jump_keys="true"
+           label="Land Options"
+           layout="topleft"
+           name="Land"
+           tear_off="true">
+          <menu_item_check
+             label="Show Property Lines"
+             layout="topleft"
+             name="Property Lines"
+             shortcut="control|alt|shift|P">
+            <menu_item_check.on_check
+               control="ShowPropertyLines" />
+            <menu_item_check.on_click
+               function="ToggleControl"
+               parameter="ShowPropertyLines" />
+          </menu_item_check>
+          <menu_item_check
+             label="Show Land Owners"
+             layout="topleft"
+             name="Land Owners">
+            <menu_item_check.on_check
+               control="ShowParcelOwners" />
+            <menu_item_check.on_click
+               function="ToggleControl"
+               parameter="ShowParcelOwners" />
+          </menu_item_check>
+          <menu_item_check
+             label="Show Ban Lines"
+             layout="topleft"
+             name="Ban Lines">
+            <menu_item_check.on_check
+               control="ShowBanLines" />
+            <menu_item_check.on_click
+               function="ToggleControl"
+               parameter="ShowBanLines" />
+          </menu_item_check>
+        </menu>
         <menu_item_separator
          layout="topleft" />
         <menu
@@ -351,7 +389,7 @@
          shortcut="control|shift|M">
             <menu_item_check.on_check
              function="Floater.Visible"
-			 parameter="mini_map" />
+             parameter="mini_map" />
             <menu_item_check.on_click
              function="Floater.Toggle"
              parameter="mini_map" />
@@ -369,7 +407,7 @@
         </menu_item_call>
         <menu_item_separator
          layout="topleft" />
-	<menu
+    <menu
          create_jump_keys="true"
          label="Sun Settings"
          layout="topleft"
@@ -430,87 +468,78 @@
         </menu>
        <menu_item_separator
          layout="topleft" />
-	<menu_item_check
-         label="Build"
+    </menu>
+    <menu
+     create_jump_keys="true"
+     label="Build"
+     layout="topleft"
+     name="BuildTools"
+     tear_off="true"
+     visible="true">
+       <menu_item_check
+         label="Show Build Tools"
          layout="topleft"
-         name="Build"
-         shortcut="B">
+         name="Show Build Tools"
+         shortcut="control|B">
             <menu_item_check.on_check
              function="Build.Active" />
             <menu_item_check.on_click
              function="Build.Toggle" />
             <menu_item_check.on_enable
              function="Build.Enabled" />
-        </menu_item_check>
-    </menu>
-    <menu
-     label="Help"
-     layout="topleft"
-     name="Help"
-     tear_off="true">
-        <menu_item_call
-         label="[SECOND_LIFE] Help"
-         layout="topleft"
-         name="Second Life Help"
-         shortcut="F1">
-            <menu_item_call.on_click
-             function="ShowFloater"
-             parameter="help f1" />
-        </menu_item_call>
-        <menu_item_call
-         label="Tutorial"
-         layout="topleft"
-         name="Tutorial">
-            <menu_item_call.on_click
-             function="Floater.Show"
-             parameter="hud" />
-        </menu_item_call>
-        <menu_item_check
-         label="Show Quick Tips"
-         layout="topleft"
-         name="Show Quick Tips">
-            <menu_item_check.on_check
-             function="Help.CheckShowFirstTimeTip" />
-            <menu_item_check.on_click
-             function="Help.ShowQuickTips" />
-        </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"
-             name="Report Abuse">
-                <menu_item_call.on_click
-                 function="ShowFloater"
-                 parameter="complaint reporter" />
-            </menu_item_call>
-        <menu_item_separator
-             layout="topleft" />
-        <menu_item_call
-         label="About [APP_NAME]"
-         layout="topleft"
-         name="About Second Life">
-            <menu_item_call.on_click
-             function="Floater.Show"
-             parameter="sl_about" />
-        </menu_item_call>
-    </menu>
-    <menu
-     create_jump_keys="true"
-     label="Tools"
-     layout="topleft"
-     name="BuildTools"
-     tear_off="true"
-     visible="false">
+       </menu_item_check>
+       <menu
+          create_jump_keys="true"
+          label="Select Build Tool"
+          layout="topleft"
+          name="Select Tool"
+          tear_off="true">
+         <menu_item_call
+			label="Focus Tool"
+			layout="topleft"
+			name="Focus"
+			shortcut="control|1">
+           <menu_item_call.on_click
+              function="Tools.SelectTool"
+              parameter="focus" />
+         </menu_item_call>
+         <menu_item_call
+			label="Move Tool"
+			layout="topleft"
+			name="Move"
+			shortcut="control|2">
+           <menu_item_call.on_click
+              function="Tools.SelectTool"
+              parameter="move" />
+         </menu_item_call>
+         <menu_item_call
+			label="Edit Tool"
+			layout="topleft"
+			name="Edit"
+			shortcut="control|3">
+           <menu_item_call.on_click
+              function="Tools.SelectTool"
+              parameter="edit" />
+         </menu_item_call>
+         <menu_item_call
+			label="Create Tool"
+			layout="topleft"
+			name="Create"
+			shortcut="control|4">
+           <menu_item_call.on_click
+              function="Tools.SelectTool"
+              parameter="create" />
+         </menu_item_call>
+         <menu_item_call
+			label="Land Tool"
+			layout="topleft"
+			name="Land"
+			shortcut="control|5">
+           <menu_item_call.on_click
+              function="Tools.SelectTool"
+              parameter="land" />
+         </menu_item_call>
+	   </menu>
         <menu
          create_jump_keys="true"
          label="Edit"
@@ -612,6 +641,159 @@
                  function="Edit.EnableDeselect" />
             </menu_item_call>
         </menu>
+        <menu_item_separator
+           layout="topleft" />
+        <menu_item_call
+           label="Link"
+           layout="topleft"
+           name="Link"
+           shortcut="control|L">
+          <menu_item_call.on_click
+             function="Tools.Link" />
+          <menu_item_call.on_enable
+             function="Tools.EnableLink" />
+        </menu_item_call>
+        <menu_item_call
+           label="Unlink"
+           layout="topleft"
+           name="Unlink"
+           shortcut="control|shift|L">
+          <menu_item_call.on_click
+             function="Tools.Unlink" />
+          <menu_item_call.on_enable
+             function="Tools.EnableUnlink" />
+        </menu_item_call>
+        <menu_item_separator
+           layout="topleft" />
+        <menu_item_call
+           label="Focus on Selection"
+           layout="topleft"
+           name="Focus on Selection"
+           shortcut="H">
+          <menu_item_call.on_click
+             function="Tools.LookAtSelection"
+             parameter="focus" />
+          <menu_item_call.on_enable
+             function="Tools.SomethingSelectedNoHUD" />
+        </menu_item_call>
+        <menu_item_call
+           label="Zoom to Selection"
+           layout="topleft"
+           name="Zoom to Selection"
+           shortcut="shift|H">
+          <menu_item_call.on_click
+             function="Tools.LookAtSelection"
+             parameter="zoom" />
+          <menu_item_call.on_enable
+             function="Tools.SomethingSelectedNoHUD" />
+        </menu_item_call>
+        <menu_item_separator
+           layout="topleft" />
+        <menu
+         create_jump_keys="true"
+         label="Object"
+         layout="topleft"
+         name="Object"
+         tear_off="true">
+          <menu_item_call
+			 label="Buy"
+			 layout="topleft"
+			 name="Menu Object Take"
+			 visible="true">
+			<menu_item_call.on_click
+               function="Tools.BuyOrTake" />
+			<menu_item_call.on_enable
+               function="Tools.EnableBuyOrTake"
+               name="EnableBuyOrTake"
+               parameter="Buy,Take" />
+          </menu_item_call>
+          <menu_item_call
+			 label="Take Copy"
+			 layout="topleft"
+			 name="Take Copy">
+			<menu_item_call.on_click
+               function="Tools.TakeCopy" />
+			<menu_item_call.on_enable
+               function="Tools.EnableTakeCopy" />
+          </menu_item_call>
+          <menu_item_call
+			 label="Save Back to My Inventory"
+			 layout="topleft"
+			 name="Save Object Back to My Inventory">
+			<menu_item_call.on_click
+               function="Tools.SaveToInventory" />
+			<menu_item_call.on_enable
+               function="Tools.EnableSaveToInventory" />
+          </menu_item_call>
+          <menu_item_call
+			 label="Save Back to Object Contents"
+			 layout="topleft"
+			 name="Save Object Back to Object Contents">
+			<menu_item_call.on_click
+               function="Tools.SaveToObjectInventory" />
+			<menu_item_call.on_enable
+               function="Tools.EnableSaveToObjectInventory" />
+          </menu_item_call>
+		</menu>
+        <menu
+           create_jump_keys="true"
+           label="Scripts"
+           layout="topleft"
+           name="Scripts"
+           tear_off="true">
+          <menu_item_call
+             label="Recompile Scripts (Mono)"
+             layout="topleft"
+             name="Mono">
+            <menu_item_call.on_click
+               function="Tools.SelectedScriptAction"
+               parameter="compile mono" />
+            <menu_item_call.on_enable
+               function="EditableSelectedMono" />
+          </menu_item_call>
+          <menu_item_call
+             label="Recompile Scripts (LSL)"
+             layout="topleft"
+             name="LSL">
+            <menu_item_call.on_click
+               function="Tools.SelectedScriptAction"
+               parameter="compile lsl" />
+            <menu_item_call.on_enable
+               function="EditableSelected" />
+          </menu_item_call>
+          <menu_item_call
+             label="Reset Scripts"
+             layout="topleft"
+             name="Reset Scripts">
+            <menu_item_call.on_click
+               function="Tools.SelectedScriptAction"
+               parameter="reset" />
+            <menu_item_call.on_enable
+               function="EditableSelected" />
+          </menu_item_call>
+          <menu_item_call
+             label="Set Scripts to Running"
+             layout="topleft"
+             name="Set Scripts to Running">
+            <menu_item_call.on_click
+               function="Tools.SelectedScriptAction"
+               parameter="start" />
+            <menu_item_call.on_enable
+               function="EditableSelected" />
+          </menu_item_call>
+          <menu_item_call
+             label="Set Scripts to Not Running"
+             layout="topleft"
+             name="Set Scripts to Not Running">
+            <menu_item_call.on_click
+               function="Tools.SelectedScriptAction"
+               parameter="stop" />
+            <menu_item_call.on_enable
+               function="EditableSelected" />
+          </menu_item_call>
+        </menu>
+        <menu_item_separator
+           layout="topleft" />
         <menu
          create_jump_keys="true"
          label="Options"
@@ -800,196 +982,68 @@
                      parameter="CheesyBeacon" />
                 </menu_item_check>
             </menu>
-            <menu
-             create_jump_keys="true"
-             label="Land"
-             layout="topleft"
-             name="Land"
-             tear_off="true">
-                <menu_item_check
-                 label="Property Lines"
-                 layout="topleft"
-                 name="Property Lines"
-                 shortcut="control|alt|shift|P">
-                    <menu_item_check.on_check
-                     control="ShowPropertyLines" />
-                    <menu_item_check.on_click
-                     function="ToggleControl"
-                     parameter="ShowPropertyLines" />
-                </menu_item_check>
-                <menu_item_check
-                 label="Land Owners"
-                 layout="topleft"
-                 name="Land Owners">
-                    <menu_item_check.on_check
-                     control="ShowParcelOwners" />
-                    <menu_item_check.on_click
-                     function="ToggleControl"
-                     parameter="ShowParcelOwners" />
-                </menu_item_check>
-                <menu_item_check
-                 label="Ban Lines"
-                 layout="topleft"
-                 name="Ban Lines">
-                    <menu_item_check.on_check
-                     control="ShowBanLines" />
-                    <menu_item_check.on_click
-                     function="ToggleControl"
-                     parameter="ShowBanLines" />
-                </menu_item_check>
-            </menu>
         </menu>
-        <menu
-         create_jump_keys="true"
-         label="Actions"
+    </menu>
+    <menu
+     label="Help"
+     layout="topleft"
+     name="Help"
+     tear_off="true">
+        <menu_item_call
+         label="[SECOND_LIFE] Help"
          layout="topleft"
-         name="Actions"
-         tear_off="true">
-            <menu_item_call
-             label="Link"
-             layout="topleft"
-             name="Link"
-             shortcut="control|L">
-                <menu_item_call.on_click
-                 function="Tools.Link" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableLink" />
-            </menu_item_call>
-            <menu_item_call
-             label="Unlink"
-             layout="topleft"
-             name="Unlink"
-             shortcut="control|shift|L">
-                <menu_item_call.on_click
-                 function="Tools.Unlink" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableUnlink" />
-            </menu_item_call>
-            <menu_item_separator
-             layout="topleft" />
-            <menu_item_call
-             label="Focus on Selection"
-             layout="topleft"
-             name="Focus on Selection"
-             shortcut="H">
-                <menu_item_call.on_click
-                 function="Tools.LookAtSelection"
-                 parameter="focus" />
-                <menu_item_call.on_enable
-                 function="Tools.SomethingSelectedNoHUD" />
-            </menu_item_call>
-            <menu_item_call
-             label="Zoom to Selection"
-             layout="topleft"
-             name="Zoom to Selection"
-             shortcut="shift|H">
-                <menu_item_call.on_click
-                 function="Tools.LookAtSelection"
-                 parameter="zoom" />
-                <menu_item_call.on_enable
-                 function="Tools.SomethingSelectedNoHUD" />
-            </menu_item_call>
-            <menu_item_separator
+         name="Second Life Help"
+         shortcut="F1">
+            <menu_item_call.on_click
+             function="ShowFloater"
+             parameter="help f1" />
+        </menu_item_call>
+        <menu_item_call
+         label="Tutorial"
+         layout="topleft"
+         name="Tutorial">
+            <menu_item_call.on_click
+             function="Floater.Show"
+             parameter="hud" />
+        </menu_item_call>
+        <menu_item_check
+         label="Show Quick Tips"
+         layout="topleft"
+         name="Show Quick Tips">
+            <menu_item_check.on_check
+             function="Help.CheckShowFirstTimeTip" />
+            <menu_item_check.on_click
+             function="Help.ShowQuickTips" />
+        </menu_item_check>
+        <menu_item_separator
              layout="topleft" />
-            <menu_item_call
-             label="Buy Object"
-             layout="topleft"
-             name="Menu Object Take"
-             visible="false">
-                <menu_item_call.on_click
-                 function="Tools.BuyOrTake" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableBuyOrTake"
-                 name="EnableBuyOrTake"
-                 parameter="Buy,Take" />
-            </menu_item_call>
-            <menu_item_call
-             label="Take Copy"
-             layout="topleft"
-             name="Take Copy">
-                <menu_item_call.on_click
-                 function="Tools.TakeCopy" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableTakeCopy" />
-            </menu_item_call>
-            <menu_item_call
-             label="Save Object Back to My Inventory"
+        <menu_item_call
+             label="Report Bug..."
              layout="topleft"
-             name="Save Object Back to My Inventory">
-                <menu_item_call.on_click
-                 function="Tools.SaveToInventory" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableSaveToInventory" />
-            </menu_item_call>
-            <menu_item_call
-             label="Save Object Back to Object Contents"
+             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"
-             name="Save Object Back to Object Contents">
+             name="Report Abuse">
                 <menu_item_call.on_click
-                 function="Tools.SaveToObjectInventory" />
-                <menu_item_call.on_enable
-                 function="Tools.EnableSaveToObjectInventory" />
+                 function="ShowFloater"
+                 parameter="complaint reporter" />
             </menu_item_call>
-            <menu_item_separator
+        <menu_item_separator
              layout="topleft" />
-            <menu
-             create_jump_keys="true"
-             label="Recompile Scripts in Selection"
-             layout="topleft"
-             name="Recompile Scripts in Selection"
-             tear_off="true">
-                <menu_item_call
-                 label="Mono"
-                 layout="topleft"
-                 name="Mono">
-                    <menu_item_call.on_click
-                     function="Tools.SelectedScriptAction"
-                     parameter="compile mono" />
-                    <menu_item_call.on_enable
-                     function="EditableSelectedMono" />
-                </menu_item_call>
-                <menu_item_call
-                 label="LSL"
-                 layout="topleft"
-                 name="LSL">
-                    <menu_item_call.on_click
-                     function="Tools.SelectedScriptAction"
-                     parameter="compile lsl" />
-                    <menu_item_call.on_enable
-                     function="EditableSelected" />
-                </menu_item_call>
-            </menu>
-            <menu_item_call
-             label="Reset Scripts in Selection"
-             layout="topleft"
-             name="Reset Scripts in Selection">
-                <menu_item_call.on_click
-                 function="Tools.SelectedScriptAction"
-                 parameter="reset" />
-                <menu_item_call.on_enable
-                 function="EditableSelected" />
-            </menu_item_call>
-            <menu_item_call
-             label="Set Scripts to Running in Selection"
-             layout="topleft"
-             name="Set Scripts to Running in Selection">
-                <menu_item_call.on_click
-                 function="Tools.SelectedScriptAction"
-                 parameter="start" />
-                <menu_item_call.on_enable
-                 function="EditableSelected" />
-            </menu_item_call>
-            <menu_item_call
-             label="Set Scripts to Not Running in Selection"
-             layout="topleft"
-             name="Set Scripts to Not Running in Selection">
-                <menu_item_call.on_click
-                 function="Tools.SelectedScriptAction"
-                 parameter="stop" />
-                <menu_item_call.on_enable
-                 function="EditableSelected" />
-            </menu_item_call>
-        </menu>
+        <menu_item_call
+         label="About [APP_NAME]"
+         layout="topleft"
+         name="About Second Life">
+            <menu_item_call.on_click
+             function="Floater.Show"
+             parameter="sl_about" />
+        </menu_item_call>
     </menu>
     <menu
      label="Advanced"
@@ -1035,7 +1089,6 @@
                  function="World.AlwaysRun" />
             </menu_item_check>
             <menu_item_check
-             control_name="FlyBtnState"
              label="Fly"
              layout="topleft"
              name="Fly"
@@ -1827,7 +1880,7 @@
              function="Advanced.ShowDebugSettings"
              parameter="all" />
         </menu_item_call>
-	 <menu_item_check
+     <menu_item_check
          label="Debug (QA) Mode"
          layout="topleft"
          name="Debug Mode"
@@ -2210,8 +2263,7 @@
         <menu_item_check
          label="View Admin Options"
          layout="topleft"
-         name="View Admin Options"
-         shortcut="control|alt|V">
+         name="View Admin Options">
             <menu_item_check.on_check
              function="Advanced.CheckViewAdminOptions"
              parameter="ViewAdminOptions" />
@@ -2497,7 +2549,7 @@
              name="Simple Web Browser Test">
                 <menu_item_call.on_click
                  function="Floater.Show"
-				 parameter="html_simple.http://www.secondlife.com" />
+                 parameter="html_simple.http://www.secondlife.com" />
             </menu_item_call>
             <menu_item_call
              label="UI/Color Settings"
@@ -2666,7 +2718,7 @@
              name="Show Font Test">
                 <menu_item_call.on_click
                  function="Floater.Show"
-				 parameter="font_test" />
+                 parameter="font_test" />
             </menu_item_call>
             <menu_item_call
              label="Load from XML..."
@@ -3144,7 +3196,7 @@
          name="God Tools">
             <menu_item_call.on_click
              function="Floater.Show"
-			 parameter="god_tools" />
+             parameter="god_tools" />
             <menu_item_call.on_enable
              function="EnableGodCustomerService" />
         </menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 98c9ec868ac46e140c6e1f1e213760e1c9d3a387..8b20918700c21c3ded8f2af582091bf6be079813 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4495,7 +4495,7 @@ Link to this from a web page to give others easy access to this location, or try
    icon="alertmodal.tga"
    name="GraphicsPreferencesHelp"
    type="alertmodal">
-This panel controls window size and resolution and the quality of the client&apos;s graphics.  The Preferences &gt; Graphics interface allows you to choose between four graphics levels: Low, Mid, High, and Ultra. You may also customize your graphics settings by checking the Custom checkbox and manipulating the following settings:
+This panel controls window size and resolution and the quality of the client&apos;s graphics.  The Preferences &gt; Graphics interface allows you to choose between four graphics levels: Low, Mid, High, and Ultra. You may also customize your graphics settings by clicking the Advanced button and manipulating the following settings:
 
 Shaders: Enable or disable various types of pixel shaders.
 
@@ -5029,7 +5029,7 @@ You must have payment information on file to visit this area.  Do you want to go
    icon="alertmodal.tga"
    name="MissingString"
    type="alertmodal">
-How odd. The string [STRING_NAME] is missing from strings.xml
+The string [STRING_NAME] is missing from strings.xml
   </notification>
 
   <notification
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
index 8977f30a51071d9d818bfb8372cf0af44a4f711e..f5af8e7b309aa2e80538f08a26106600c45ffd57 100644
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
@@ -1,47 +1,53 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	follows="bottom|right"
+<panel	
 	name="panel_activeim_row"
 	layout="topleft"
+	follows="left|right"
 	top="0"
 	left="0"
-	height="40"
-	width="332"
+	height="35"
+	width="318"
 	background_visible="true"
 	bevel_style="in"
 	bg_alpha_color="0 0 0 0">
-	<chiclet_im
+  <chiclet_im_p2p
 		name="chiclet"
 		layout="topleft"
-		top="4"
-		left="10"
-		height="26"
+		follows="left"
+		top="5"
+		left="5"
+		height="25"
 		width="45">
-	</chiclet_im>
+  </chiclet_im_p2p>
 	<text
 		type="string"
 		name="contact_name"
 		layout="topleft"
 		top="8"
-		left="70"
-		height="20"
-		width="230"
+		left_pad="6"
+		height="28"
+		width="235"
 		length="1"
-		follows="left|top|right|bottom"
-		font="SansSerifBigBold"
-		text_color="White">Contact Name</text>
-	<button
-		name="hide_btn"
-		layout="topleft"
-		top="10"
-		left="310"
-		height="20"
-		width="20"
-		label=""
-		image_unselected="toast_hide_btn.tga"
-		image_disabled="toast_hide_btn.tga"
-		image_selected="toast_hide_btn.tga"
-		image_hover_selected="toast_hide_btn.tga"
-		image_disabled_selected="toast_hide_btn.tga">
-	</button>
+		follows="right|left"
+		font="SansSerifBold"
+		text_color="White">
+    Contact Name
+  </text>
+  <button
+    top="5"
+    left_pad="5"
+    width="15"
+    height="15"
+    layout="topleft"
+    follows="right"
+    name="hide_btn"
+    mouse_opaque="true"
+    label=""
+    tab_stop="false"
+    image_unselected="toast_hide_btn.tga"
+    image_disabled="toast_hide_btn.tga"
+    image_selected="toast_hide_btn.tga"
+    image_hover_selected="toast_hide_btn.tga"
+    image_disabled_selected="toast_hide_btn.tga"
+  />
 </panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5c8a8ee2081ad20d78d6066edc58d5e8d3492240
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="305"
+ layout="topleft"
+ name="block_list_panel"
+ min_height="350"
+ min_width="240"
+ width="280">
+    <text 
+     follows="top|left|right"
+     font="SansSerifHugeBold"
+     height="20"
+     layout="topleft"
+     left="10" 
+     name="title_text"
+     text_color="white"
+     top="0" 
+     width="250">
+        Blocked List
+     </text>
+     <button 
+     follows="top|right"
+     height="25"
+     image_overlay="BackArrow_Off"
+     layout="topleft"
+     name="back"
+     right="-9"
+     tab_stop="false" 
+     top="0"
+     width="25"/>
+    <scroll_list
+     follows="left|top|right|bottom"
+     height="200"
+     layout="topleft"
+     left="5"
+     name="blocked"
+     tool_tip="List of currently blocked residents"
+     top="30"
+     width="270" />
+    <button
+     follows="left|bottom"
+     height="20"
+     label="Block Resident..."
+     label_selected="Block Resident..."
+     layout="topleft"
+     left_delta="0"
+     name="Block resident..."
+     tool_tip="Pick a resident to block"
+     top_pad="4"
+     width="210">
+        <button.commit_callback
+         function="Block.ClickPick" />
+    </button>
+    <button
+     follows="left|bottom"
+     height="20"
+     label="Block object by name..."
+     label_selected="Block object by name..."
+     layout="topleft"
+     left_delta="0"
+     name="Block object by name..."
+     top_pad="4"
+     width="210" >
+        <button.commit_callback
+         function="Block.ClickBlockByName" />
+    </button>
+    <button
+     enabled="false"
+     follows="left|bottom"
+     height="20"
+     label="Unblock"
+     label_selected="Unblock"
+     layout="topleft"
+     left_delta="0"
+     name="Unblock"
+     tool_tip="Remove resident or object from blocked list"
+     top_pad="4"
+     width="210" >
+        <button.commit_callback
+         function="Block.ClickRemove" />
+    </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index b6d0678cfb997824cb84fdc2182503ab9e75c92a..79ca839f2815ed0151cc2b3588b8cd89313da50c 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -216,41 +216,7 @@
          left="0"
          top="0"
          width="5"/>
-        <layout_panel
-         auto_resize="false"
-         follows="right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         name="im_well_panel"
-         width="40"
-         top="0"
-         min_width="40" 
-         user_resize="false">
-            <chiclet_notification
-             follows="right"
-             height="25"
-             layout="topleft"
-             left="0"
-             name="im_well"
-             top="2"
-             width="40">
-              <button
-               image_selected="im_notifications.tga"
-               image_unselected="im_notifications.tga"/>
-              <unread_notifications
-               width="20"
-               height="20"
-               left="18"
-               top="23"/>
-<!-- 
-			  <chiclet_notification.commit_callback
-				 function="Notification.Show"
-				 parameter="ClickUnimplemented" />
- -->               				 
-			</chiclet_notification>
-        </layout_panel>
-        <icon
+      <icon
          auto_resize="false"
          color="0 0 0 0"
          follows="left|right"
@@ -300,7 +266,7 @@
              top="2"
              width="48">
               <button
-               image_selected="bottom_tray_sys_notifications.tga"
+               image_selected="bottom_tray_sys_notifications_selected.tga"
                image_unselected="bottom_tray_sys_notifications.tga"/>
               <unread_notifications
                width="20"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 291803fbc5266621b2d0285f6b456b5b37b4caef..5dd03656c66d41daf6502be23f5fb4952877b417 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -9,6 +9,30 @@
  name="panel_edit_pick"
  top="0"
  width="255">
+   <text
+     type="string"
+     length="1"
+     follows="top"
+     font="SansSerifHugeBold"
+     height="15"
+     layout="topleft"
+     left="10"
+     name="title"
+     text_color="white"
+     top="5"
+     width="250">
+        Edit Pick
+    </text>
+   <button
+     follows="top|right"
+     height="20"
+     image_overlay="BackArrow_Off"
+     layout="topleft"
+     name="back_btn"
+     picture_style="true"
+     right="-20"
+     top="7"
+     width="20" />
    <scroll_container
      color="DkGray2"
      follows="left|top|right|bottom"
@@ -27,64 +51,42 @@
      left="0"
      width="240"
      height="575">
-    <text
-     type="string"
-     length="1"
-     follows="top"
-     font="SansSerifHugeBold"
-     height="15"
-     layout="topleft"
-     left="10"
-     name="title"
-     text_color="white"
-     top="17"
-     width="250">
-        Edit Pick
-    </text>
     <panel
      background_visible="true"
      bg_alpha_color="DkGray2"
-     width="280"
+     width="220"
      follows="left|right|top|bottom"
      height="560"
      layout="topleft"
+     left="0"
+     top="0">
+    <texture_picker
+     follows="left|top|right"
+     height="190"
+     width="220"
+     layout="topleft"
+     top="20"
      left="10"
-     right="-10"
-     top_pad="5">
-        <panel
-         follows="left|top|right"
-         height="150"
-         layout="topleft"
-         left="10"
-         right="-10"
-         top="10">
-            <panel
-             follows="left|top|right"
-             height="150"
-             layout="topleft" >
-                <texture_picker
-                 follows="left|top|right"
-                 height="150"
-                 layout="topleft"
-                 name="pick_snapshot" />
-            </panel>
-            <icon
-             height="16"
-             image_name="image_edit_icon.tga"
-             layout="topleft"
-             name="edit_icon"
-             right="-25"
-             top="30"
-             visible="false"
-             width="16" />
-        </panel>
+     name="pick_snapshot" />
+     <icon
+     height="16"
+     image_name="image_edit_icon.tga"
+     layout="topleft"
+     name="edit_icon"
+     left="245"
+     top="35"
+     visible="true"
+     width="16" />
         <text
          type="string"
          length="1"
          follows="left|top"
-         height="16"
+         height="15"
+         font="SansSerifSmall"
+         font.style="BOLD"
          layout="topleft"
          left="10"
+         top="215"
          name="Name:"
          text_color="white">
             Name:
@@ -95,46 +97,49 @@
          height="20"
          layout="topleft"
          left="10"
+         top_pad="2"
          max_length="63"
          name="pick_name"
-         right="-10"
          text_color="black"
-         width="255" />
+         width="220" />
         <text
          type="string"
          length="1"
          follows="left|top"
-         height="30"
+         height="15"
+         font="SansSerifSmall"
+         font.style="BOLD"
          layout="topleft"
          left="10"
+         top_pad="20"
          name="description_label"
-         text_color="white"
-         v_pad="15"
-         valign="center">
+         text_color="white">
             Description:
         </text>
         <text_editor
          follows="left|top|right"
          height="100"
+         width="220"
          hide_scrollbar="true"
          layout="topleft"
          left="10"
+         top_pad="2"
          max_length="1023"
          name="pick_desc"
          text_color="black"
-         right="-10"
          word_wrap="true" />
         <text
          type="string"
          length="1"
+         font="SansSerifSmall"
+         font.style="BOLD"
          follows="left|top"
-         height="20"
+         height="15"
          layout="topleft"
          left="10"
          name="location_label"
          text_color="white"
-         v_pad="15"
-         valign="bottom">
+         top_pad="20">
             Location:
         </text>
         <text
@@ -146,10 +151,9 @@
          left="10"
          name="pick_location"
          right="-10"
+         top_pad="2"
          text_color="white"
-         v_pad="10"
          width="250"
-         valign="center"
          word_wrap="true">
             loading...
         </text>
@@ -166,7 +170,7 @@
     </scroll_container>
     <panel
      follows="left|right|bottom"
-     height="25"
+     height="30"
      label="bottom_panel"
      layout="topleft"
      left="10"
@@ -174,21 +178,21 @@
      top_pad="2">
         <button
          follows="bottom|left"
-         height="20"
+         height="25"
          label="Save [WHAT]"
          layout="topleft"
          name="save_changes_btn"
-         right="-120"
-         top="5"
+         left="0"
+         top="0"
          width="130" />
         <button
          follows="bottom|left"
-         height="20"
+         height="25"
          label="Cancel"
          layout="topleft"
          name="cancel_btn"
-         right="-10"
-         top="5"
-         width="90" />
+         left_pad="5"
+         top_delta="0"
+         width="130" />
     </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index c0366437db4f00b09901b8a4dd44f610e9fda096..0d6d8ba97d41054e5067d5c9a0534a0de04f4bf8 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -12,7 +12,45 @@
  name="edit_profile_panel"
  top="10"
  width="255">
-   <scroll_container
+   <string
+    name="CaptionTextAcctInfo">
+       [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+   </string>
+   <string
+    name="AcctTypeResident"
+    value="Resident" />
+   <string
+    name="AcctTypeTrial"
+    value="Trial" />
+   <string
+    name="AcctTypeCharterMember"
+    value="Charter Member" />
+   <string
+    name="AcctTypeEmployee"
+    value="Linden Lab Employee" />
+   <string
+    name="PaymentInfoUsed"
+    value="Payment Info Used" />
+   <string
+    name="PaymentInfoOnFile"
+    value="Payment Info On File" />
+   <string
+    name="NoPaymentInfoOnFile"
+    value="No Payment Info On File" />
+   <string
+    name="AgeVerified"
+    value="Age-verified" />
+   <string
+    name="NotAgeVerified"
+    value="Not Age-verified" />
+   <string
+    name="partner_edit_link_url">
+       http://www.secondlife.com/account/partners.php?lang=en
+   </string>
+   <string
+    name="no_partner_text"
+    value="None" />
+  <scroll_container
      color="DkGray2"
      follows="left|top|right|bottom"
      height="300"
@@ -34,7 +72,7 @@
      background_visible="true"
      bg_alpha_color="DkGray2"
      follows="left|top|right|bottom"  
-     height="620"
+     height="750"
      layout="topleft"
      left="0"
      name="data_panel" 
@@ -243,11 +281,10 @@
          top_pad="15"
          value="Account Status:"
          width="100" />
-        <link
+        <text
          type="string"
          follows="left|top"
          font="SansSerifSmall"
-	 font.style="UNDERLINE"
          height="15"
          layout="topleft"
          left_pad="10"
@@ -277,15 +314,14 @@
          top_pad="15"
          value="Partner:"
          width="100" />
-	<link
+        <text
          follows="left|top"
          height="15"
-	 font.style="UNDERLINE"
          layout="topleft"
          left_pad="10"
          name="partner_edit_link"
          top_delta="0"
-         value="Edit"
+         value="[[URL] Edit]"
          width="100" />
         <panel
          follows="left|top|right"
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 2de41a9ee6f3a4a67df86077d4cca440d2763330..6ba4d131177df203a8363b526db76cf9bf934b1f 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
@@ -69,6 +69,7 @@
      left_delta="0"
      name="founder_name"
      top_pad="10"
+     use_ellipses="true"
      width="140" />
     <button
      top="632"
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index 8ebf1b69a798a9756050d8ac4ac5e2624880b034..f97daf922f08a11b0de9faa591ccdd8135e7bb7c 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -1,8 +1,12 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0"
-	height="200" label="instant_message" layout="topleft" left="0"
+	height="155" label="instant_message" layout="topleft" left="0"
 	name="panel_group_notify" top="0" width="350">
-	<panel background_visible="true" bevel_style="in" bg_alpha_color="black"
+    <string
+     name="message_max_lines_count">
+        4
+    </string>
+	<panel follows="top" background_visible="true" bevel_style="in" bg_alpha_color="black"
 		height="50" label="header" layout="topleft" left="0" name="header"
 		top="0" width="350">
 		<icon follows="left|top|right|bottom" height="40"  width="40" layout="topleft"
@@ -13,21 +17,61 @@
 			Sender Name / Group Name
         </text>
 	</panel>
-	<text_editor type="string" length="1" bg_readonly_color="0 0 0 0"
-		follows="left|top|right|bottom" height="70" hide_scrollbar="true"
-		hide_border="true" layout="topleft" top="55" left="25" name="message"
-		text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true">
-		Message
-		Body
-    </text_editor>
-	<icon follows="left|top|right|bottom" height="16" width="16"
-		layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" />
+	<text
+     follows="top"
+     height="20"
+     layout="topleft"
+     left="25"
+     name="subject"
+     text_color="GroupNotifyTextColor"
+     font="SansSerifBig"
+     top="60"
+     use_ellipses="true"
+     value="subject"
+     width="300"
+     word_wrap="true">
+     subject 
+    </text>
+    <text
+     follows="top"
+     height="20"
+     layout="topleft"
+     left="25"
+     name="datetime"
+     text_color="GroupNotifyTextColor"
+     font="SansSerif"
+     top="80"
+     use_ellipses="true"
+     value="datetime"
+     width="300"
+     word_wrap="true">
+     datetime
+    </text>
+    <text
+     follows="left|top|bottom|right"
+     height="0"
+     layout="topleft"
+     left="25"
+     name="message"
+     text_color="GroupNotifyTextColor"
+     top="100"
+     use_ellipses="true"
+     value="message"
+     width="300"
+     word_wrap="true"
+     visible="true" >
+    </text>
+    <icon
+	  follows="left|bottom|right" height="15" width="15"
+		layout="topleft" bottom="122" left="25" mouse_opaque="true" name="attachment_icon" visible="true"
+	/>
 	<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"
-		type="string" length="1" follows="left|top|right|bottom" layout="topleft"
-		left="45" top="135" height="15" width="280" name="attachment"
-		text_color="GroupNotifyTextColor">
+		type="string" length="1" follows="left|bottom|right" layout="topleft"
+		left="45" bottom="122" height="15" width="280" name="attachment"
+		text_color="GroupNotifyTextColor" visible="true">
 		Attachment
-        </text>
-	<button label="OK" layout="topleft" top="170" left="140" height="20"
-		width="70" name="btn_ok" />
-</panel>
+     </text>
+
+	<button label="OK" layout="topleft" bottom="145" left="140" height="20"
+		width="70" name="btn_ok" follows="bottom" />
+</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index 169fde7b475a2d95454093769820d49c8e56081e..ace456918c1cf15a67dc6dc068b5c824c3a07c5e 100644
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -10,6 +10,10 @@
  name="im_panel"
  top="0"
  width="350">
+    <string
+     name="message_max_lines_count">
+        6
+    </string>
     <panel
      background_visible="true"
      bevel_style="in"
@@ -56,7 +60,7 @@
          width="50" />
     </panel>
     <text
-     follows="left|bottom|right"
+     follows="left|top|bottom|right"
      height="60"
      layout="topleft"
      left="10"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index dee911a45dede5b7afa5ccef3dc11f89571fb3da..80dca8c0c152da85220ad9fce2071b8a14ff6a98 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -107,8 +107,8 @@
 	<!--      picture_style="true" -->
 	<!--      top_delta="0" -->
 	<!--      width="168" /> -->
-	    
-	    <search_editor
+
+        <search_combo_box
 	     bevel_style="none"
 	     border_style="line"
 	     border.border_thickness="0"
@@ -118,12 +118,15 @@
 	     height="22"
 	     label="Search"
 	     layout="topleft"
-	     left_pad="7"
+	     right="-10"
 	     mouse_opaque="false"
-	     name="search_input"
+	     name="search_combo_box"
 	     tool_tip="Search"
 	     top_delta="0"
-	     width="200" />        
+	     width="200" >
+         <combo_editor
+          label="Search" />
+        </search_combo_box>
 	</panel>
 	
     <favorites_bar
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 22823ea98ba303dfdb250d5083599822779d1073..e5a417e3d07d3787370951ed4d0a3fea5487205d 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -130,24 +130,15 @@
                  min_height="100"
                  name="tab_online"
                  title="Online">
-                    <panel
-                     follows="all"
-                     height="150"
-                     layout="topleft"
-                     left="0"
-                     name="tab_online_panel"
-                     top="100"
-                     width="285">
                         <avatar_list
                          draw_heading="false"
                          follows="all"
-                         height="145"
+                         height="150"
                          layout="topleft"
                          left="0"
                          name="avatars_online"
                          top="0"
                          width="285" />
-                    </panel>
                 </accordion_tab>
                 <accordion_tab
                  can_resize="false"
@@ -155,14 +146,6 @@
                  min_height="100"
                  name="tab_all"
                  title="All">
-                    <panel
-                     follows="all"
-                     height="260"
-                     layout="topleft"
-                     left="0"
-                     name="tab_all_panel"
-                     top="100"
-                     width="285">
                         <avatar_list
                          draw_heading="false"
                          follows="all"
@@ -172,7 +155,6 @@
                          name="avatars_all"
                          top="0"
                          width="285" />
-                    </panel>
                 </accordion_tab>
             </accordion>
             <panel
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 80fa99c257ba5d0bdacf0ccc466792a31b14873e..c33011670202fd48e4622233f5e586b5d32f7506 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -8,24 +8,6 @@
  name="panel_pick_info"
  top="0"
  width="255">
-   <scroll_container
-     color="DkGray2"
-     follows="left|top|right|bottom"
-     height="300"
-     layout="topleft"
-     left="0"
-     name="profile_scroll"
-     reserve_scroll_corner="true"
-     opaque="true"
-     width="255">
-    <panel
-     name="scroll_content_panel"
-     follows="left|top|right"
-     layout="topleft"
-     top="0"
-     left="0"
-     width="240"
-     height="575">
     <text
      follows="top"
      font="SansSerifHugeBold"
@@ -47,6 +29,24 @@
      right="-20"
      top="7"
      width="20" />
+    <scroll_container
+     color="DkGray2"
+     follows="left|top|right|bottom"
+     height="300"
+     layout="topleft"
+     left="0"
+     name="profile_scroll"
+     reserve_scroll_corner="true"
+     opaque="true"
+     width="255">
+    <panel
+     name="scroll_content_panel"
+     follows="left|top|right"
+     layout="topleft"
+     top="0"
+     left="0"
+     width="240"
+     height="575">
     <panel
      background_visible="true"
      bg_alpha_color="DkGray2"
@@ -55,80 +55,51 @@
      layout="topleft"
      left="0"
      min_height="300"
-     top="30"
-     width="255">
+     top="0"
+     width="220">
         <texture_picker
          enabled="false"
          follows="left|top|right"
-         height="300"
+         height="190"
          layout="topleft"
          left="10"
          name="pick_snapshot"
-         top="10"
-         width="245" />
-        <text
-         follows="left|top"
-         font="SansSerifBigBold"
-         height="15"
-         layout="topleft"
-         left="10"
-         name="Name:"
-         text_color="white"
-         value="Name:" />
+         top="20"
+         width="220" />
         <text
          follows="left|top|right"
-         height="15"
+         height="20"
          layout="topleft"
+         font="SansSerif"
+         font.style="BOLD"
          left="10"
          name="pick_name"
-         right="-10"
          text_color="white"
          value="[name]"
          word_wrap="true" />
         <text
          follows="left|top"
-         font="SansSerifBigBold"
-         height="15"
+         height="30"
          layout="topleft"
          left="10"
-         name="description_label"
+         name="pick_location"
          text_color="white"
-         top_pad="20"
-         valign="center"
-         value="Description:" />
+         top_pad="10"
+         width="255"
+         word_wrap="true"
+         value="[loading...]" />
         <text
          follows="left|top|right"
-         height="60"
+         height="150"
          layout="topleft"
          left="10"
+         top_pad="20"
          name="pick_desc"
-         right="-10"
          text_color="white"
-         valign="center"
+         width="225"
          value="[description]"
-         width="255"
          word_wrap="true" />
-        <text
-         follows="left|top"
-         font="SansSerifBigBold"
-         height="20"
-         layout="topleft"
-         left="10"
-         name="location_label"
-         text_color="white"
-         top_pad="20"
-         valign="bottom"
-         value="Location:" />
-        <text
-         follows="left|top"
-         height="30"
-         layout="topleft"
-         left="10"
-         name="pick_location"
-         text_color="white"
-         valign="center"
-         value="[loading...]" />
-    </panel>
+    </panel> 
     </panel>
     </scroll_container>
     <panel
@@ -136,9 +107,8 @@
      height="30"
      layout="topleft"
      top_pad="2"
-     left="8"
-     name="buttons"
-     right="-10">
+     left="10"
+     name="buttons">
         <button
          follows="bottom|left"
          font="SansSerifSmallBold"
@@ -148,14 +118,14 @@
          left="0"
          name="edit_btn"
          top="0"
-         width="50" />
+         width="80" />
         <button
          follows="bottom|left"
          font="SansSerifSmallBold"
          height="25"
          label="Teleport"
          layout="topleft"
-         left_pad="2"
+         left_pad="3"
          name="teleport_btn"
          top="0"
          width="80" />
@@ -165,9 +135,9 @@
          height="25"
          label="Map"
          layout="topleft"
-         left_pad="2"
+         left_pad="3"
          name="show_on_map_btn"
          top="0"
-         width="100" />
+         width="80" />
     </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 6f4110067be409b1c7fffac458758cf2676c4e23..4c8c4efbe7a3b20e9c28077d8cf84ebc1b670df3 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -8,6 +8,26 @@
  name="picture_item"
  top="0"
  width="275">
+    <icon
+     height="120" 
+     image_name="ListItem_Over"
+     left="0" 
+     mouse_opaque="false"
+     name="hovered_icon" 
+     top="0"
+     scale_image="true" 
+     visible="false"
+     width="270"/>
+    <icon
+     height="120" 
+     image_name="ListItem_Select"
+     left="0" 
+     mouse_opaque="false"
+     name="selected_icon"
+     top="0"
+     scale_image="true"
+     visible="false"
+     width="270"/>
     <texture_picker
      allow_no_texture="true"
      default_image_name="None"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index ff161cc2abdb45a1de831394f931c7742cf07986..c56bb32feb0e7066c117e14c5440059db96aab19 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -28,11 +28,11 @@
          opaque="true"
          top="0"
          width="284">
-            <panel
+            <list
              height="115"
              layout="topleft"
              left="0"
-             name="back_panel"
+             name="picks_list"
              top="0"
              width="284" />
         </scroll_container>
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 060d84b2e4870e1930ec72bf9037a5a6f7ac4030..88bf3d3b229d08e84c23f3f047b345985ff02475 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -120,7 +120,7 @@
      height="10"
      left="30"
      text_color="EmphasisColor"
-     name="text_box1"
+     name="heading1"
      top_pad="30"
      width="270">
 Camera:
@@ -166,7 +166,7 @@ Camera:
      length="1"
      height="10"
      left="30"
-     name="text_box1"
+     name="heading2"
      width="270">
 Automatic positioning for:
 	</text>
@@ -194,7 +194,7 @@ Automatic positioning for:
      height="10"
      left="30"
      text_color="EmphasisColor"
-     name="text_box1"
+     name="heading3"
      top_pad="30"
      width="270">
 My Avatar:
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 95d8d2ce2a08844e0d251c645678eb1da33432c9..70292a38aa0101d7d42a1128f9095251522b1889 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -260,7 +260,7 @@
      label="Show my name"
      layout="topleft"
      left_delta="0"
-     name="show_my_name_checkbox"
+     name="show_my_name_checkbox1"
      top_pad="5"
      width="300" />
     <check_box
@@ -280,7 +280,7 @@
      label="Show group titles"
      layout="topleft"
      left_delta="-175"
-     name="show_all_title_checkbox"
+     name="show_all_title_checkbox1"
      top_pad="5"
      width="300" />
     <text
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index d90be9ea25d194a86c4e82454c708c2b0e195c3b..135dcb167b9608889fa261b4e785343d023f5d5d 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -167,11 +167,10 @@
          width="255">
              Homepage:
         </text>
-        <link
+        <text
          follows="left|top|right"
          height="15"
          layout="topleft"
-	 font.style="UNDERLINE"
          left="10"
          name="homepage_edit"
          top_pad="5"
@@ -212,11 +211,10 @@
          top_pad="15"
          value="Account Status:"
          width="100" />
-       <!-- <link
+       <!-- <text
          type="string"
          follows="left|top"
          font="SansSerifSmall"
-	 font.style="UNDERLINE"
          height="15"
          layout="topleft"
          left_pad="10"
@@ -246,16 +244,15 @@
          top_pad="15"
          value="Partner:"
          width="100" />
-	<!--<link
+        <text
          follows="left|top"
          height="15"
-	 font.style="UNDERLINE"
          layout="topleft"
          left_pad="10"
          name="partner_edit_link"
          top_delta="0"
-         value="Edit"
-         width="100" />  -->
+         value="[[URL] Edit]"
+         width="100" />
         <panel
          follows="left|top|right"
          height="15"
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 32223d542df341f2555adb0545ec7b2a162f12fa..9aa2c304f24840376b2a549fa3ea67689ddbcd99 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -8,6 +8,14 @@
  min_width="240"
  name="panel_target_profile"
  width="305">
+    <string
+     name="status_online">
+        Online
+    </string>
+    <string
+     name="status_offline">
+        Offline
+    </string>
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 4f23c4d26d3eeaa129df64efbccf6ed7a77c5850..9b2461db7cbc2b1119190c6f809698fd009a52a6 100644
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -99,12 +99,12 @@
                      halign="left"
                      height="100"
                      layout="topleft"
-                     left="30"
+                     left="45"
                      line_spacing="2"
                      name="message_text"
                      text_color="LoginProgressBoxTextColor"
                      top="145"
-                     width="610" />
+                     width="550" />
                 </layout_panel>
                 <layout_panel
                  height="200"
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index e9eac2c9dc6f8c3c57fe42659d351a1d329ad6ad..e1666753649e93279e8f1b8f0ae3fbe3eb0a0d21 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -57,6 +57,13 @@
         label="Group Info" 
         border="true"
       />
+      <panel 
+        class="panel_block_list_sidetray"
+        name="panel_block_list_sidetray" 
+        filename="panel_block_list_sidetray.xml" 
+        label="Blocked Residents &amp; Objects"
+        border="true"
+      />
 
     </panel_container>
   </sidetray_tab>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 4c9b1897d581cd7b9e037e15b9f8063afd6e2dc5..b8152a4956bab632b927ee2e77bf1233f9f415bb 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -74,6 +74,18 @@
 	<string name="TooltipMustSingleDrop">Only a single item can be dragged here</string>	
 	<string name="TooltipAltLeft">Alt-Left arrow for previous tab</string>	
 	<string name="TooltipAltRight">Alt-Right arrow for next tab</string>	
+
+	<!-- tooltips for Urls -->
+	<string name="TooltipHttpUrl">Click to view this web page</string>
+	<string name="TooltipSLURL">Click to view this location's information</string>
+	<string name="TooltipAgentUrl">Click to view this resident's profile</string>
+	<string name="TooltipGroupUrl">Click to view this group's description</string>
+	<string name="TooltipEventUrl">Click to view this event's description</string>
+	<string name="TooltipClassifiedUrl">Click to view this classified</string>
+	<string name="TooltipParcelUrl">Click to view this parcel's description</string>
+	<string name="TooltipTeleportUrl">Click to teleport to this location</string>
+	<string name="TooltipObjectIMUrl">Click to view this object's description</string>
+	<string name="TooltipSLAPP">Click to run the secondlife:// command</string>
 	
 	<!-- ButtonToolTips, llfloater.cpp -->
 	<string name="BUTTON_CLOSE_DARWIN">Close (&#8984;-W)</string>
@@ -259,6 +271,7 @@
 
 	<!-- IM -->
 	<string name="IM_logging_string">-- Instant message logging enabled --</string>
+	<string name="Unnamed">(Unnamed)</string>
 	
 	<!-- Sim Access labels -->
 	<string name="SIM_ACCESS_PG">PG</string>
@@ -288,358 +301,1439 @@
 	<string name="choose_the_directory">Choose Directory</string>
 	
 	<!-- LSL Usage Hover Tips -->
-	<string name="LSLTipSleepTime">Sleeps script for [SLEEP_TIME] seconds.</string>
+	<string name="LSLTipSleepTime">
+Sleeps script for [SLEEP_TIME] seconds.
+	</string>
 	
-	<string name="LSLTipText_llSin">float llSin(float theta)\ntheta in radians</string>
-	<string name="LSLTipText_llCos">float llCos(float theta)\ntheta in radians</string>
-	<string name="LSLTipText_llTan">float llTan(float theta)\ntheta radians</string>
-	<string name="LSLTipText_llAtan2">float llAtan2(float y, float x)</string>
-	<string name="LSLTipText_llSqrt">float llSqrt(float val)\nreturns 0 and triggers a Math Error for imaginary results</string>
-	<string name="LSLTipText_llPow">float llPow(float base, float exponent)\nreturns 0 and triggers Math Error for imaginary results</string>
-	<string name="LSLTipText_llAbs">integer llAbs(integer val)</string>
-	<string name="LSLTipText_llFabs">float llFabs(float val)</string>
-	<string name="LSLTipText_llFrand">float llFrand(float mag)\nreturns random number in range [0,mag)</string>
-	<string name="LSLTipText_llFloor">integer llFloor(float val)\nreturns largest integer value &lt;= val</string>
-	<string name="LSLTipText_llCeil">integer llCeil(float val)\nreturns smallest integer value &gt;= val</string>
-	<string name="LSLTipText_llRound">integer llRound(float val)\nreturns val rounded to the nearest integer</string>
-	<string name="LSLTipText_llVecMag">float llVecMag(vector v)\nreturns the magnitude of v</string>
-	<string name="LSLTipText_llVecNorm">vector llVecNorm(vector v)\nreturns the v normalized</string>
-	<string name="LSLTipText_llVecDist">float llVecDist(vector v1, vector v2)\nreturns the 3D distance between v1 and v2</string>
-	<string name="LSLTipText_llRot2Euler">vector llRot2Euler(rotation q)\nreturns the Euler representation (roll, pitch, yaw) of q</string>
-	<string name="LSLTipText_llEuler2Rot">rotation llEuler2Rot(vector v)\nreturns the rotation representation of Euler Angles v</string>
-	<string name="LSLTipText_llAxes2Rot">rotation llAxes2Rot(vector fwd, vector left, vector up)\nreturns the rotation defined by the coordinate axes</string>
-	<string name="LSLTipText_llRot2Fwd">vector llRot2Fwd(rotation q)\nreturns the forward vector defined by q</string>
-	<string name="LSLTipText_llRot2Left">vector llRot2Left(rotation q)\nreturns the left vector defined by q</string>
-	<string name="LSLTipText_llRot2Up">vector llRot2Up(rotation q)\nreturns the up vector defined by q</string>
-	<string name="LSLTipText_llRotBetween">rotation llRotBetween(vector v1, vector v2)\nreturns the rotation to rotate v1 to v2</string>
-	<string name="LSLTipText_llWhisper">llWhisper(integer channel, string msg)\nwhispers msg on channel</string>
-	<string name="LSLTipText_llSay">llSay(integer channel, string msg)\nsays msg on channel</string>
-	<string name="LSLTipText_llShout">llShout(integer channel, string msg)\nshouts msg on channel</string>
-	<string name="LSLTipText_llListen">integer llListen(integer channel, string name, key id, string msg)\nsets 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)\nmakes a listen event callback active or inactive</string>
-	<string name="LSLTipText_llListenRemove">llListenRemove(integer number)\nremoves listen event callback number</string>
-	<string name="LSLTipText_llSensor">llSensor(string name, key id, integer type, float range, float arc)\nPerforms a single scan 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)</string>
-	<string name="LSLTipText_llSensorRepeat">llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)\nsets 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()\nremoves sensor</string>
-	<string name="LSLTipText_llDetectedName">string llDetectedName(integer number)\nreturns the name of detected object number (returns empty string if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedKey">key llDetectedKey(integer number)\nreturns the key of detected object number (returns empty key if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedOwner">key llDetectedOwner(integer number)\nreturns the key of detected object&apos;s owner (returns empty key if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedType">integer llDetectedType(integer number)\nreturns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedPos">vector llDetectedPos(integer number)\nreturns the position of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedVel">vector llDetectedVel(integer number)\nreturns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedGrab">vector llDetectedGrab(integer number)\nreturns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedRot">rotation llDetectedRot(integer number)\nreturns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not valid sensed object)</string>
-	<string name="LSLTipText_llDetectedGroup">integer llDetectedGroup(integer number)\nReturns TRUE if detected object is part of same group as owner</string>
-	<string name="LSLTipText_llDetectedLinkNumber">integer llDetectedLinkNumber(integer number)\nreturns the link position of the triggered event for touches and collisions only</string>
-	<string name="LSLTipText_llDie">llDie()\ndeletes the object</string>
-	<string name="LSLTipText_llGround">float llGround(vector v)\nreturns the ground height below the object position + v</string>
-	<string name="LSLTipText_llCloud">float llCloud(vector v)\nreturns the cloud density at the object position + v</string>
-	<string name="LSLTipText_llWind">vector llWind(vector v)\nreturns the wind velocity at the object position + v</string>
-	<string name="LSLTipText_llSetStatus">llSetStatus(integer status, integer value)\nsets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value</string>
-	<string name="LSLTipText_llGetStatus">integer llGetStatus(integer status)\ngets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)</string>
-	<string name="LSLTipText_llSetScale">llSetScale(vector scale)\nsets the scale</string>
-	<string name="LSLTipText_llGetScale">vector llGetScale()\ngets the scale</string>
-	<string name="LSLTipText_llSetColor">llSetColor(vector color, integer face)\nsets the color</string>
-	<string name="LSLTipText_llGetAlpha">float llGetAlpha(integer face)\ngets the alpha</string>
-	<string name="LSLTipText_llSetAlpha">llSetAlpha(float alpha, integer face)\nsets the alpha</string>
-	<string name="LSLTipText_llGetColor">vector llGetColor(integer face)\ngets the color</string>
-	<string name="LSLTipText_llSetTexture">llSetTexture(string texture, integer face)\nsets the texture of face</string>
-	<string name="LSLTipText_llScaleTexture">llScaleTexture(float scales, float scalet, integer face)\nsets the texture s, t scales for the chosen face</string>
-	<string name="LSLTipText_llOffsetTexture">llOffsetTexture(float offsets, float offsett, integer face)\nsets the texture s, t offsets for the chosen face</string>
-	<string name="LSLTipText_llRotateTexture">llRotateTexture(float rotation, integer face)\nsets the texture rotation for the chosen face</string>
-	<string name="LSLTipText_llGetTexture">string llGetTexture(integer face)\ngets the texture of face (if it&apos;s a texture in the object inventory, otherwise the key in a string)</string>
-	<string name="LSLTipText_llSetPos">llSetPos(vector pos)\nsets the position (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llGetPos">vector llGetPos()\ngets the position (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llGetLocalPos">vector llGetLocalPos()\ngets the position relative to the root (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llSetRot">llSetRot(rotation rot)\nsets the rotation (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llGetRot">rotation llGetRot()\ngets the rotation (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llGetLocalRot">rotation llGetLocalRot()\ngets the rotation local to the root (if the script isn&apos;t physical)</string>
-	<string name="LSLTipText_llSetForce">llSetForce(vector force, integer local)\nsets force on object, in local coords if local == TRUE (if the script is physical)</string>
-	<string name="LSLTipText_llGetForce">vector llGetForce()\ngets the force (if the script is physical)</string>
-	<string name="LSLTipText_llTarget">integer llTarget(vector position, float range)\nset positions within range of position as a target and return an ID for the target</string>
-	<string name="LSLTipText_llTargetRemove">llTargetRemove(integer number)\nremoves target number</string>
-	<string name="LSLTipText_llRotTarget">integer llRotTarget(rotation rot, float error)\nset 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)\nremoves rotational target number</string>
-	<string name="LSLTipText_llMoveToTarget">llMoveToTarget(vector target, float tau)\ncritically damp to target in tau seconds (if the script is physical)</string>
-	<string name="LSLTipText_llStopMoveToTarget">llStopMoveToTarget()\nStops critically damped motion</string>
-	<string name="LSLTipText_llApplyImpulse">llApplyImpulse(vector force, integer local)\napplies impulse to object, in local coords if local == TRUE (if the script is physical)</string>
-	<string name="LSLTipText_llApplyRotationalImpulse">llApplyRotationalImpulse(vector force, integer local)\napplies rotational impulse to object, in local coords if local == TRUE (if the script is physical)</string>
-	<string name="LSLTipText_llSetTorque">llSetTorque(vector torque, integer local)\nsets the torque of object, in local coords if local == TRUE (if the script is physical)</string>
-	<string name="LSLTipText_llGetTorque">vector llGetTorque()\ngets the torque (if the script is physical)</string>
-	<string name="LSLTipText_llSetForceAndTorque">llSetForceAndTorque(vector force, vector torque, integer local)\nsets the force and torque of object, in local coords if local == TRUE (if the script is physical)</string>
-	<string name="LSLTipText_llGetVel">vector llGetVel()\ngets the velocity</string>
-	<string name="LSLTipText_llGetAccel">vector llGetAccel()\ngets the acceleration</string>
-	<string name="LSLTipText_llGetOmega">vector llGetOmega()\ngets the omega</string>
-	<string name="LSLTipText_llGetTimeOfDay">float llGetTimeOfDay()\ngets the time in seconds since Second Life server midnight (or since server up-time; whichever is smaller)</string>
-	<string name="LSLTipText_llGetWallclock">float llGetWallclock()\ngets the time in seconds since midnight</string>
-	<string name="LSLTipText_llGetTime">float llGetTime()\ngets the time in seconds since creation</string>
-	<string name="LSLTipText_llResetTime">llResetTime()\nsets the time to zero</string>
-	<string name="LSLTipText_llGetAndResetTime">float llGetAndResetTime()\ngets the time in seconds since creation and sets the time to zero</string>
-	<string name="LSLTipText_llSound">llSound(string sound, float volume, integer queue, integer loop)\nplays sound at volume and whether it should loop or not</string>
-	<string name="LSLTipText_llPlaySound">llPlaySound(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0)</string>
-	<string name="LSLTipText_llLoopSound">llLoopSound(string sound, float volume)\nplays attached sound looping indefinitely at volume (0.0 - 1.0)</string>
-	<string name="LSLTipText_llLoopSoundMaster">llLoopSoundMaster(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), declares it a sync master</string>
-	<string name="LSLTipText_llLoopSoundSlave">llLoopSoundSlave(string sound, float volume)\nplays 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)\nplays 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)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object</string>
-	<string name="LSLTipText_llStopSound">llStopSound()\nStops currently attached sound</string>
-	<string name="LSLTipText_llPreloadSound">llPreloadSound(string sound)\npreloads a sound on viewers within range</string>
-	<string name="LSLTipText_llGetSubString">string llGetSubString(string src, integer start, integer end)\nreturns the indicated substring</string>
-	<string name="LSLTipText_llDeleteSubString">string llDeleteSubString(string src, integer start, integer end)\nremoves the indicated substring and returns the result</string>
-	<string name="LSLTipText_llInsertString">string llInsertString(string dst, integer position, string src)\ninserts src into dst at position and returns the result</string>
-	<string name="LSLTipText_llToUpper">string llToUpper(string src)\nconvert src to all upper case and returns the result</string>
-	<string name="LSLTipText_llToLower">string llToLower(string src)\nconvert src to all lower case and returns the result</string>
-	<string name="LSLTipText_llGiveMoney">llGiveMoney(key destination, integer amount)\ntransfer amount of money 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)\nMake 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)\nMake a fountain of particles</string>
-	<string name="LSLTipText_llMakeSmoke">llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake smoke like particles</string>
-	<string name="LSLTipText_llMakeFire">llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake fire like particles</string>
-	<string name="LSLTipText_llRezObject">llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstanciate owners 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)\nCause object name to point it&apos;s forward axis towards target</string>
-	<string name="LSLTipText_llStopLookAt">llStopLookAt()\nStop causing object name to point at a target</string>
-	<string name="LSLTipText_llSetTimerEvent">llSetTimerEvent(float sec)\nCause the timer event to be triggered every sec seconds</string>
-	<string name="LSLTipText_llSleep">llSleep(float sec)\nPut script to sleep for sec seconds</string>
-	<string name="LSLTipText_llGetMass">float llGetMass()\nGet the mass of task name that script is attached to</string>
-	<string name="LSLTipText_llCollisionFilter">llCollisionFilter(string name, key id, integer accept)\nif 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)\nTake controls from agent task has permissions for.  If (accept == (controls &amp; input)), send input to task.  If pass_on send to agent also.</string>
-	<string name="LSLTipText_llReleaseControls">llReleaseControls()\nStop taking inputs</string>
-	<string name="LSLTipText_llAttachToAvatar">llAttachToAvatar(integer attachment)\nAttach to avatar task has permissions for at point attachment</string>
-	<string name="LSLTipText_llDetachFromAvatar">llDetachFromAvatar()\nDrop off of avatar</string>
-	<string name="LSLTipText_llTakeCamera">llTakeCamera(key avatar)\nMove avatar&apos;s viewpoint to task</string>
-	<string name="LSLTipText_llReleaseCamera">llReleaseCamera(key avatar)\nReturn camera to agent</string>
-	<string name="LSLTipText_llGetOwner">key llGetOwner()\nReturns the owner of the task</string>
-	<string name="LSLTipText_llInstantMessage">llInstantMessage(key user, string message)\nIMs message to the user</string>
-	<string name="LSLTipText_llEmail">llEmail(string address, string subject, string message)\nSends email to address with subject and message</string>
-	<string name="LSLTipText_llGetNextEmail">llGetNextEmail(string address, string subject)\nGet the next waiting email with appropriate address and/or subject (if blank they are ignored)</string>
-	<string name="LSLTipText_llGetKey">key llGetKey()\nGet the key for the task the script is attached to</string>
-	<string name="LSLTipText_llSetBuoyancy">llSetBuoyancy(float buoyancy)\nSet the tasks buoyancy (0 is none, &lt; 1.0 sinks, 1.0 floats, > 1.0 rises)</string>
-	<string name="LSLTipText_llSetHoverHeight">llSetHoverHeight(float height, integer water, float tau)\nCritically damps to a height (either above ground level or above the higher of land and water if water == TRUE)</string>
-	<string name="LSLTipText_llStopHover">llStopHover()\nStop hovering to a height</string>
-	<string name="LSLTipText_llMinEventDelay">llMinEventDelay(float delay)\nSet the minimum time between events being handled</string>
-	<string name="LSLTipText_llSoundPreload">llSoundPreload(string sound)\npreloads a sound on viewers within range</string>
-	<string name="LSLTipText_llRotLookAt">llRotLookAt(rotation target, F32 strength, F32 damping)\nCause object name to point it&apos;s forward axis towards target</string>
-	<string name="LSLTipText_llStringLength">integer llStringLength(string str)\nReturns the length of string</string>
-	<string name="LSLTipText_llStartAnimation">llStartAnimation(string anim)\nStart animation anim for agent that owns object</string>
-	<string name="LSLTipText_llStopAnimation">llStopAnimation(string anim)\nStop animation anim for agent that owns object</string>
-	<string name="LSLTipText_llPointAt">llPointAt(vector pos)\nMake agent that owns object point at pos</string>
-	<string name="LSLTipText_llStopPointAt">llStopPointAt()\nStop agent that owns object pointing</string>
-	<string name="LSLTipText_llTargetOmega">llTargetOmega(vector axis, float spinrate, float gain)\nAttempt to spin at spinrate with strength gain</string>
-	<string name="LSLTipText_llGetStartParameter">integer llGetStartParameter()\nGet's the start paramter passed to llRezObject</string>
-	<string name="LSLTipText_llGodLikeRezObject">llGodLikeRezObject(key inventory, vector pos)\nrez directly off of a UUID if owner has dog-bit set</string>
-	<string name="LSLTipText_llRequestPermissions">llRequestPermissions(key agent, integer perm)\nask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)</string>
-	<string name="LSLTipText_llGetPermissionsKey">key llGetPermissionsKey()\nReturn agent that permissions are enabled for.  NULL_KEY if not enabled</string>
-	<string name="LSLTipText_llGetPermissions">integer llGetPermissions()\nreturn what permissions have been enabled</string>
-	<string name="LSLTipText_llGetLinkNumber">integer llGetLinkNumber()\nReturns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, etc)</string>
-	<string name="LSLTipText_llSetLinkColor">llSetLinkColor(integer linknumber, vector color, integer face)\nIf a task exists in the link chain at linknumber, set face to color</string>
-	<string name="LSLTipText_llCreateLink">llCreateLink(key target, integer parent)\nAttempt 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</string>
-	<string name="LSLTipText_llBreakLink">llBreakLink(integer linknum)\nDelinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)</string>
-	<string name="LSLTipText_llBreakAllLinks">llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)</string>
-	<string name="LSLTipText_llGetLinkKey">key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set</string>
-	<string name="LSLTipText_llGetLinkName">string llGetLinkName(integer linknum)\nGet the name of linknumber in link set</string>
-	<string name="LSLTipText_llGetInventoryNumber">integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL</string>
-	<string name="LSLTipText_llGetInventoryName">string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type</string>
-	<string name="LSLTipText_llSetScriptState">llSetScriptState(string name, integer run)\nControl the state of a script name.</string>
-	<string name="LSLTipText_llGetEnergy">float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum</string>
-	<string name="LSLTipText_llGiveInventory">llGiveInventory(key destination, string inventory)\nGive inventory to destination</string>
-	<string name="LSLTipText_llRemoveInventory">llRemoveInventory(string inventory)\nRemove the named inventory item</string>
-	<string name="LSLTipText_llSetText">llSetText(string text, vector color, float alpha)\nSet text floating over object</string>
-	<string name="LSLTipText_llWater">float llWater(vector v)\nreturns the water height below the object position + v</string>
-	<string name="LSLTipText_llPassTouches">llPassTouches(integer pass)\nif pass == TRUE, touches are passed from children on to parents (default is FALSE)</string>
-	<string name="LSLTipText_llRequestAgentData">key llRequestAgentData(key id, integer data)\nRequests data about agent id.  When data is available the dataserver event will be raised</string>
-	<string name="LSLTipText_llRequestInventoryData">key llRequestInventoryData(string name)\nRequests data from object's inventory object.  When data is available the dataserver event will be raised</string>
-	<string name="LSLTipText_llSetDamage">llSetDamage(float damage)\nSets the amount of damage that will be done to an object that this task hits.  Task will be killed.</string>
-	<string name="LSLTipText_llTeleportAgentHome">llTeleportAgentHome(key id)\nTeleports agent on owner's land to agent's home location</string>
-	<string name="LSLTipText_llModifyLand">llModifyLand(integer action, integer size)\nModify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)\non size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)</string>
-	<string name="LSLTipText_llCollisionSound">llCollisionSound(string impact_sound, float impact_volume)\nSuppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)</string>
-	<string name="LSLTipText_llCollisionSprite">llCollisionSprite(string impact_sprite)\nSuppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)</string>
-	<string name="LSLTipText_llGetAnimation">string llGetAnimation(key id)\nGet the currently playing locomotion animation for avatar id</string>
-	<string name="LSLTipText_llResetScript">llResetScript()\nResets the script</string>
-	<string name="LSLTipText_llMessageLinked">llMessageLinked(integer linknum, integer num, string str, key id)\nSends num, str, and id to members of the link set (LINK_ROOT sends to root task in a linked set,\nLINK_SET sends to all tasks,\nLINK_ALL_OTHERS to all other tasks,\nLINK_ALL_CHILDREN to all children,\nLINK_THIS to the task the script it is in)</string>
-	<string name="LSLTipText_llPushObject">llPushObject(key id, vector impulse, vector ang_impulse, integer local)\nApplies impulse and ang_impulse to object id</string>
-	<string name="LSLTipText_llPassCollisions">llPassCollisions(integer pass)\nif pass == TRUE, collisions are passed from children on to parents (default is FALSE)</string>
-	<string name="LSLTipText_llGetScriptName">llGetScriptName()\nReturns the script name</string>
-	<string name="LSLTipText_llGetNumberOfSides">integer llGetNumberOfSides()\nReturns the number of sides</string>
-	<string name="LSLTipText_llAxisAngle2Rot">rotation llAxisAngle2Rot(vector axis, float angle)\nReturns the rotation generated angle about axis</string>
-	<string name="LSLTipText_llRot2Axis">vector llRot2Axis(rotation rot)\nReturns the rotation axis represented by rot</string>
-	<string name="LSLTipText_llRot2Angle">float llRot2Angle(rotation rot)\nReturns the rotation angle represented by rot</string>
-	<string name="LSLTipText_llAcos">float llAcos(float val)\nReturns the arccosine in radians of val</string>
-	<string name="LSLTipText_llAsin">float llAsin(float val)\nReturns the arcsine in radians of val</string>
-	<string name="LSLTipText_llAngleBetween">float llAngleBetween(rotation a, rotation b)\nReturns angle between rotation a and b</string>
-	<string name="LSLTipText_llGetInventoryKey">key llGetInventoryKey(string name)\nReturns the key of the inventory name</string>
-	<string name="LSLTipText_llAllowInventoryDrop">llAllowInventoryDrop(integer add)\nIf add == TRUE, users without permissions can still drop inventory items onto task</string>
-	<string name="LSLTipText_llGetSunDirection">vector llGetSunDirection()\nReturns the sun direction on the simulator</string>
-	<string name="LSLTipText_llGetTextureOffset">vector llGetTextureOffset(integer side)\nReturns the texture offset of side in the x and y components of a vector</string>
-	<string name="LSLTipText_llGetTextureScale">vector llGetTextureScale(integer side)\nReturns the texture scale of side in the x and y components of a vector</string>
-	<string name="LSLTipText_llGetTextureRot">float llGetTextureRot(integer side)\nReturns the texture rotation of side</string>
-	<string name="LSLTipText_llSubStringIndex">integer llSubStringIndex(string source, string pattern)\nFinds index in source where pattern first appears (returns -1 if not found)</string>
-	<string name="LSLTipText_llGetOwnerKey">key llGetOwnerKey(key id)\nFind the owner of id</string>
-	<string name="LSLTipText_llGetCenterOfMass">vector llGetCenterOfMass()\nGet the object's center of mass</string>
-	<string name="LSLTipText_llListSort">list llListSort(list src, integer stride, integer ascending)\nSort the list into blocks of stride in ascending order if ascending == TRUE.  Note that sort only works between same types.</string>
-	<string name="LSLTipText_llGetListLength">integer llGetListLength(list src)\nGet the number of elements in the list</string>
-	<string name="LSLTipText_llList2Integer">integer llList2Integer(list src, integer index)\nCopy the integer at index in the list</string>
-	<string name="LSLTipText_llList2Float">float llList2Float(list src, integer index)\nCopy the float at index in the list</string>
-	<string name="LSLTipText_llList2String">string llList2String(list src, integer index)\nCopy the string at index in the list</string>
-	<string name="LSLTipText_llList2Key">key llList2Key(list src, integer index)\nCopy the key at index in the list</string>
-	<string name="LSLTipText_llList2Vector">vector llList2Vector(list src, integer index)\nCopy the vector at index in the list</string>
-	<string name="LSLTipText_llList2Rot">rotation llList2Rot(list src, integer index)\nCopy the rotation at index in the list</string>
-	<string name="LSLTipText_llList2List">list llList2List(list src, integer start, integer end)\nCopy the slice of the list from start to end</string>
-	<string name="LSLTipText_llDeleteSubList">list llDeleteSubList(list src, integer start, integer end)\nRemove the slice from the list and return the remainder</string>
-	<string name="LSLTipText_llGetListEntryType">integer llGetListEntryType(list src, integer index)\nReturns the type of the index entry in the list\n(TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list)</string>
-	<string name="LSLTipText_llList2CSV">string llList2CSV(list src)\nCreate a string of comma separated values from list</string>
-	<string name="LSLTipText_llCSV2List">list llCSV2List(string src)\nCreate a list from a string of comma separated values</string>
-	<string name="LSLTipText_llListRandomize">list llListRandomize(list src, integer stride)\nReturns a randomized list of blocks of size stride</string>
-	<string name="LSLTipText_llList2ListStrided">list llList2ListStrided(list src, integer start, integer end, integer stride)\nCopy the strided slice of the list from start to end</string>
-	<string name="LSLTipText_llGetRegionCorner">vector llGetRegionCorner()\nReturns a vector with the south west corner x,y position of the region the object is in</string>
-	<string name="LSLTipText_llListInsertList">list llListInsertList(list dest, list src, integer start)\nInserts src into dest at position start</string>
-	<string name="LSLTipText_llListFindList">integer llListFindList(list src, list test)\nReturns the start of the first instance of test in src, -1 if not found</string>
-	<string name="LSLTipText_llGetObjectName">string llGetObjectName()\nReturns the name of the object script is attached to</string>
-	<string name="LSLTipText_llSetObjectName">llSetObjectName(string name)\nSets the objects name</string>
-	<string name="LSLTipText_llGetDate">string llGetDate()\nGets the date as YYYY-MM-DD</string>
-	<string name="LSLTipText_llEdgeOfWorld">integer llEdgeOfWorld(vector pos, vector dir)\nChecks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)</string>
-	<string name="LSLTipText_llGetAgentInfo">integer llGetAgentInfo(key id)\nGets information about agent ID.\nReturns 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)\nadjusts volume of attached sound (0.0 - 1.0)</string>
-	<string name="LSLTipText_llSetSoundQueueing">llSetSoundQueueing(integer queue)\ndetermines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)</string>
-	<string name="LSLTipText_llSetSoundRadius">llSetSoundRadius(float radius)\nestablishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)</string>
-	<string name="LSLTipText_llKey2Name">string llKey2Name(key id)\nReturns the name of the object key, iff the object is in the current simulator, otherwise the empty string</string>
-	<string name="LSLTipText_llSetTextureAnim">llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)\nAnimate the texture on the specified face/faces</string>
-	<string name="LSLTipText_llTriggerSoundLimited">llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)\nplays 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</string>
-	<string name="LSLTipText_llEjectFromLand">llEjectFromLand(key pest)\nEjects pest from land that you own</string>
-	<string name="LSLTipText_llParseString2List">list llParseString2List(string src, list separators, list spacers)\nBreaks 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)\nReturns TRUE if id is over land owner of object owns, FALSE otherwise</string>
-	<string name="LSLTipText_llGetLandOwnerAt">key llGetLandOwnerAt(vector pos)\nReturns the key of the land owner, NULL_KEY if public</string>
-	<string name="LSLTipText_llGetNotecardLine">key llGetNotecardLine(string name, integer line)\nReturns line line of notecard name via the dataserver event</string>
-	<string name="LSLTipText_llGetAgentSize">vector llGetAgentSize(key id)\nIf the agent is in the same sim as the object, returns the size of the avatar</string>
-	<string name="LSLTipText_llSameGroup">integer llSameGroup(key id)\nReturns TRUE if ID is in the same sim and has the same active group, otherwise FALSE</string>
-	<string name="LSLTipText_llUnSit">key llUnSit(key id)\nIf 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</string>
-	<string name="LSLTipText_llGroundSlope">vector llGroundSlope(vector v)\nreturns the ground slope below the object position + v</string>
-	<string name="LSLTipText_llGroundNormal">vector llGroundNormal(vector v)\nreturns the ground normal below the object position + v</string>
-	<string name="LSLTipText_llGroundContour">vector llGroundCountour(vector v)\nreturns the ground contour below the object position + v</string>
-	<string name="LSLTipText_llGetAttached">integer llGetAttached()\nreturns the object attachment point or 0 if not attached</string>
-	<string name="LSLTipText_llGetFreeMemory">integer llGetFreeMemory()\nreturns the available heap space for the current script</string>
-	<string name="LSLTipText_llGetRegionName">string llGetRegionName()\nreturns the current region name</string>
-	<string name="LSLTipText_llGetRegionTimeDilation">float llGetRegionTimeDilation()\nreturns the current time dilation as a float between 0 and 1</string>
-	<string name="LSLTipText_llGetRegionFPS">float llGetRegionFPS()\nreturns the mean region frames per second</string>
-	<string name="LSLTipText_llParticleSystem">llParticleSystem(list rules)\nCreates a particle system based on rules.  Empty list removes particle system from object.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]</string>
-	<string name="LSLTipText_llGroundRepel">llGroundRepel(float height, integer water, float tau)\nCritically 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)\nGive inventory to destination in a new category</string>
-	<string name="LSLTipText_llSetVehicleType">llSetVehicleType(integer type)\nsets vehicle to one of the default types</string>
-	<string name="LSLTipText_llSetVehicleFloatParam">llSetVehicleFloatParam(integer param, float value)\nsets the specified vehicle float parameter</string>
-	<string name="LSLTipText_llSetVehicleVectorParam">llSetVehicleVectorParam(integer param, vector vec)\nsets the specified vehicle vector parameter</string>
-	<string name="LSLTipText_llSetVehicleRotationParam">llSetVehicleVectorParam(integer param, rotation rot)\nsets the specified vehicle rotation parameter</string>
-	<string name="LSLTipText_llSetVehicleFlags">llSetVehicleFlags(integer flags)\nsets the enabled bits in 'flags'</string>
-	<string name="LSLTipText_llRemoveVehicleFlags">llRemoveVehicleFlags(integer flags)\nremoves the enabled bits in 'flags'</string>
-	<string name="LSLTipText_llSitTarget">llSitTarget(vector offset, rotation rot)\nSet the sit location for this object (if offset == &lt;0,0,0&gt; clear it)</string>
-	<string name="LSLTipText_llAvatarOnSitTarget">key llAvatarOnSitTarget()\nIf an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise</string>
-	<string name="LSLTipText_llAddToLandPassList">llAddToLandPassList(key avatar, float hours)\nAdd avatar to the land pass list for hours</string>
-	<string name="LSLTipText_llSetTouchText">llSetTouchText(string text)\nDisplays text in pie menu that acts as a touch</string>
-	<string name="LSLTipText_llSetSitText">llSetSitText(string text)\nDisplays text rather than sit in pie menu</string>
-	<string name="LSLTipText_llSetCameraEyeOffset">llSetCameraEyeOffset(vector offset)\nSets the camera eye offset used in this object if an avatar sits on it</string>
-	<string name="LSLTipText_llSetCameraAtOffset">llSetCameraAtOffset(vector offset)\nSets the camera at offset used in this object if an avatar sits on it</string>
-	<string name="LSLTipText_llDumpList2String">string llDumpList2String(list src, string separator)\nWrite the list out in a single string using separator between values</string>
-	<string name="LSLTipText_llScriptDanger">integer llScriptDanger(vector pos)\nReturns 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</string>
-	<string name="LSLTipText_llDialog">llDialog(key avatar, string message, list buttons, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nUp to 12 strings in the list form buttons.\nIf a button is clicked, the name is chatted on chat_channel.</string>
-	<string name="LSLTipText_llVolumeDetect">llVolumeDetect(integer detect)\nIf detect = TRUE, object becomes phantom but triggers collision_start and collision_end events\nwhen other objects start and stop interpenetrating.\nMust be applied to the root object.</string>
-	<string name="LSLTipText_llResetOtherScript">llResetOtherScript(string name)\nResets script name</string>
-	<string name="LSLTipText_llGetScriptState">integer llGetScriptState(string name)\nResets TRUE if script name is running</string>
-	<string name="LSLTipText_llRemoteLoadScript">Deprecated.  Please use llRemoteLoadScriptPin instead.</string>
-	<string name="LSLTipText_llSetRemoteScriptAccessPin">llSetRemoteScriptAccessPin(integer pin)\nIf pin is set to a non-zero number, the task will accept remote script\nloads via llRemoteLoadScriptPin if it passes in the correct pin.\nOthersise, llRemoteLoadScriptPin is ignored.</string>
-	<string name="LSLTipText_llRemoteLoadScriptPin">llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)\nIf the owner of the object this script is attached can modify target,\nthey are in the same region,\nand the matching pin is used,\ncopy script name onto target,\nif running == TRUE, start the script with param.</string>
-	<string name="LSLTipText_llOpenRemoteDataChannel">llOpenRemoteDataChannel()\nCreates a channel to listen for XML-RPC calls.  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)\nSend an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.\nA message identifier key is returned.\nAn XML-RPC reply will trigger a remote_data event and reference the message id.\nThe message_id is returned.</string>
-	<string name="LSLTipText_llRemoteDataReply">llRemoteDataReply(key channel, key message_id, string sdata, integer idata)\nSend 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)\nCloses XML-RPC channel.</string>
-	<string name="LSLTipText_llMD5String">string llMD5String(string src, integer nonce)\nPerforms a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce.  Returns a 32 character hex string.</string>
-	<string name="LSLTipText_llSetPrimitiveParams">llSetPrimitiveParams(list rules)\nSet primitive parameters based on rules.</string>
-	<string name="LSLTipText_llStringToBase64">string llStringToBase64(string str)\nConverts a string to the Base 64 representation of the string.</string>
-	<string name="LSLTipText_llBase64ToString">string llBase64ToString(string str)\nConverts a Base 64 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)\nDEPRECATED!  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.</string>
-	<string name="LSLTipText_llRemoteDataSetRegion">llRemoteDataSetRegion()\nIf an object using remote data channels changes regions, you must call this function to reregister the remote data channels.\nYou do not need to make this call if you don't change regions.</string>
-	<string name="LSLTipText_llLog10">float llLog10(float val)\nReturns the base 10 log of val if val &gt; 0, otherwise returns 0.</string>
-	<string name="LSLTipText_llLog">float llLog(float val)\nReturns the base e log of val if val &gt; 0, otherwise returns 0.</string>
-	<string name="LSLTipText_llGetAnimationList">list llGetAnimationList(key id)\nGets a list of all playing animations for avatar id</string>
-	<string name="LSLTipText_llSetParcelMusicURL">llSetParcelMusicURL(string url)\nSets the streaming audio URL for the parcel object is on</string>
-	<string name="LSLTipText_llGetRootPosition">vector llGetRootPosition()\nGets the global position of the root object of the object script is attached to</string>
-	<string name="LSLTipText_llGetRootRotation">rotation llGetRootRotation()\nGets the global rotation of the root object of the object script is attached to</string>
-	<string name="LSLTipText_llGetObjectDesc">string llGetObjectDesc()\nReturns the description of the object the script is attached to</string>
-	<string name="LSLTipText_llSetObjectDesc">llSetObjectDesc(string name)\nSets the object's description</string>
-	<string name="LSLTipText_llGetCreator">key llGetCreator()\nReturns the creator of the object</string>
-	<string name="LSLTipText_llGetTimestamp">string llGetTimestamp()\nGets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ</string>
-	<string name="LSLTipText_llSetLinkAlpha">llSetLinkAlpha(integer linknumber, float alpha, integer face)\nIf a prim exists in the link chain at linknumber, set face to alpha</string>
-	<string name="LSLTipText_llGetNumberOfPrims">integer llGetNumberOfPrims()\nReturns the number of prims in a link set the script is attached to</string>
-	<string name="LSLTipText_llGetNumberOfNotecardLines">key llGetNumberOfNotecardLines(string name)\nReturns number of lines in notecard 'name' via the dataserver event (cast return value to integer)</string>
-	<string name="LSLTipText_llGetBoundingBox">list llGetBoundingBox(key object)\nReturns the bounding box around an object (including any linked prims) relative to the root prim, in a list:  [ (vector) min_corner, (vector) max_corner ]</string>
-	<string name="LSLTipText_llGetGeometricCenter">vector llGetGeometricCenter()\nReturns the geometric center of the linked set the script is attached to.</string>
-	<string name="LSLTipText_llGetPrimitiveParams">list llGetPrimitiveParams(list params)\nGets primitive parameters specified in the params list.</string>
-	<string name="LSLTipText_llIntegerToBase64">string llIntegerToBase64(integer number)\nBig endian encode of of integer as a Base64 string.</string>
-	<string name="LSLTipText_llBase64ToInteger">integer llBase64ToInteger(string str)\nBig endian decode of a Base64 string into an integer.</string>
-	<string name="LSLTipText_llGetGMTclock">float llGetGMTclock()\nGets the time in seconds since midnight in GMT</string>
-	<string name="LSLTipText_llGetSimulatorHostname">string llGetSimulatorHostname()\nGets the hostname of the machine script is running on (same as string in viewer Help dialog)</string>
-	<string name="LSLTipText_llSetLocalRot">llSetLocalRot(rotation rot)\nsets the rotation of a child prim relative to the root prim</string>
-	<string name="LSLTipText_llParseStringKeepNulls">list llParseStringKeepNulls(string src, list separators, list spacers)\nBreaks 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.</string>
-	<string name="LSLTipText_llRezAtRoot">llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.\nThe last selected root object's location will be set to pos</string>
-	<string name="LSLTipText_llGetObjectPermMask">integer llGetObjectPermMask(integer mask)\nReturns the requested permission mask for the root object the task is attached to.</string>
-	<string name="LSLTipText_llSetObjectPermMask">llSetObjectPermMask(integer mask, integer value)\nSets 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)\nReturns the requested permission mask for the inventory item.</string>
-	<string name="LSLTipText_llSetInventoryPermMask">llSetInventoryPermMask(string item, integer mask, integer value)\nSets the given permission mask to the new value on the inventory item.</string>
-	<string name="LSLTipText_llGetInventoryCreator">key llGetInventoryCreator(string item)\nReturns the key for the creator of the inventory item.</string>
-	<string name="LSLTipText_llOwnerSay">llOwnerSay(string msg)\nsays msg to owner only (if owner in sim)</string>
-	<string name="LSLTipText_llRequestSimulatorData">key llRequestSimulatorData(string simulator, integer data)\nRequests data about simulator.  When data is available the dataserver event will be raised</string>
-	<string name="LSLTipText_llForceMouselook">llForceMouselook(integer mouselook)\nIf mouselook is TRUE any avatar that sits on this object is forced into mouselook mode</string>
-	<string name="LSLTipText_llGetObjectMass">float llGetObjectMass(key id)\nGet the mass of the object with key id</string>
-	<string name="LSLTipText_llListReplaceList">list llListReplaceList(list dest, list src, integer start, integer end)\nReplaces start through end of dest with src.</string>
-	<string name="LSLTipText_llLoadURL">llLoadURL(key avatar_id, string message, string url)\nShows dialog to avatar avatar_id offering to load web page at URL.  If user clicks yes, launches their web browser.</string>
-	<string name="LSLTipText_llParcelMediaCommandList">llParcelMediaCommandList(list command)\nSends a list of commands, some with arguments, to a parcel.</string>
-	<string name="LSLTipText_llParcelMediaQuery">list llParcelMediaQuery(list query)\nSends a list of queries, returns a list of results.</string>
-	<string name="LSLTipText_llModPow">integer llModPow(integer a, integer b, integer c)\nReturns 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)\nReturns the type of the inventory name</string>
-	<string name="LSLTipText_llSetPayPrice">llSetPayPrice(integer price, list quick_pay_buttons)\nSets the default amount when someone chooses to pay this object.</string>
-	<string name="LSLTipText_llGetCameraPos">vector llGetCameraPos()\nGets current camera position for agent task has permissions for.</string>
-	<string name="LSLTipText_llGetCameraRot">rotation llGetCameraRot()\nGets current camera orientation for agent task has permissions for.</string>
-	<string name="LSLTipText_llSetPrimURL">llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object.</string>
-	<string name="LSLTipText_llRefreshPrimURL">llRefreshPrimURL()\nReloads the web page shown on the sides of the object.</string>
-	<string name="LSLTipText_llEscapeURL">string llEscapeURL(string url)\nReturns and escaped/encoded version of url, replacing spaces with %20 etc.</string>
-	<string name="LSLTipText_llUnescapeURL">string llUnescapeURL(string url)\nReturns and unescaped/unencoded version of url, replacing %20 with spaces etc.</string>
-	<string name="LSLTipText_llMapDestination">llMapDestination(string simname, vector pos, vector look_at)\nOpens world map centered on region with pos highlighted.\nOnly works for scripts attached to avatar, or during touch events.\n(NOTE: look_at currently does nothing)</string>
-	<string name="LSLTipText_llAddToLandBanList">llAddToLandBanList(key avatar, float hours)\nAdd avatar to the land ban list for hours</string>
-	<string name="LSLTipText_llRemoveFromLandPassList">llRemoveFromLandPassList(key avatar)\nRemove avatar from the land pass list</string>
-	<string name="LSLTipText_llRemoveFromLandBanList">llRemoveFromLandBanList(key avatar)\nRemove avatar from the land ban list</string>
-	<string name="LSLTipText_llSetCameraParams">llSetCameraParams(list rules)\nSets multiple camera parameters at once.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]</string>
-	<string name="LSLTipText_llClearCameraParams">llClearCameraParams()\nResets all camera parameters to default values and turns off scripted camera control.</string>
-	<string name="LSLTipText_llListStatistics">float llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations.</string>
-	<string name="LSLTipText_llGetUnixTime">integer llGetUnixTime()\nGet 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)\nGet the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.</string>
-	<string name="LSLTipText_llGetRegionFlags">integer llGetRegionFlags()\nGet the region flags (REGION_FLAG_*) for the region the object is in.</string>
-	<string name="LSLTipText_llXorBase64StringsCorrect">string llXorBase64StringsCorrect(string s1, string s2)\nCorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string.  s2 repeats if it is shorter than s1.</string>
-	<string name="LSLTipText_llHTTPRequest">llHTTPRequest(string url, list parameters, string body)\nSend an HTTP request.</string>
-	<string name="LSLTipText_llResetLandBanList">llResetLandBanList()\nRemoves all residents from the land ban list.</string>
-	<string name="LSLTipText_llResetLandPassList">llResetLandPassList()\nRemoves all residents from the land access/pass list.</string>
-	<string name="LSLTipText_llGetObjectPrimCount">integer llGetObjectPrimCount(key object_id)\nReturns the total number of prims for an object.</string>
-	<string name="LSLTipText_llGetParcelPrimOwners">list llGetParcelPrimOwners(vector pos)\nReturns a list of all residents who own objects on the parcel and the number of objects they own.\nRequires owner-like permissions for the parcel.</string>
-	<string name="LSLTipText_llGetParcelPrimCount">integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)\nGets the number of prims on the parcel of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.</string>
-	<string name="LSLTipText_llGetParcelMaxPrims">integer llGetParcelMaxPrims(vector pos, integer sim_wide)\nGets the maximum number of prims allowed on the parcel at pos.</string>
-	<string name="LSLTipText_llGetParcelDetails">list llGetParcelDetails(vector pos, list params)\nGets the parcel details specified in params for the parcel at pos.\nParams is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA</string>
-	<string name="LSLTipText_llSetLinkPrimitiveParams">llSetLinkPrimitiveParams(integer linknumber, list rules)\nSet primitive parameters for linknumber based on rules.</string>
-	<string name="LSLTipText_llSetLinkTexture">llSetLinkTexture(integer link_pos, string texture, integer face)\nSets the texture of face for link_pos</string>
-	<string name="LSLTipText_llStringTrim">string llStringTrim(string src, integer trim_type)\nTrim leading and/or trailing spaces from a string.\nUses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.</string>
-	<string name="LSLTipText_llRegionSay">llRegionSay(integer channel, string msg)\nbroadcasts msg to entire region on channel (not 0.)</string>
-	<string name="LSLTipText_llGetObjectDetails">list llGetObjectDetails(key id, list params)\nGets the object details specified in params for the object with key id.\nDetails are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.</string>
-	<string name="LSLTipText_llSetClickAction">llSetClickAction(integer action)\nSets the action performed when a prim is clicked upon.</string>
-	<string name="LSLTipText_llGetRegionAgentCount">int llGetRegionAgentCount()\nreturns the number of agents in a region</string>
-	<string name="LSLTipText_llTextBox">llTextBox(key avatar, string message, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nA text box asks for input, and if entered the text is chatted on chat_channel.</string>
-	<string name="LSLTipText_llGetAgentLanguage">string llGetAgentLanguage(key id)\nGets the agents preferred language..</string>
-	<string name="LSLTipText_llDetectedTouchUV">vector llDetectedTouchUV(integer number)\nreturns the u and v coordinates in the first two components of a vector, for a triggered touch event</string>
-	<string name="LSLTipText_llDetectedTouchFace">integer llDetectedTouchFace(integer number)\nreturns the index of the face on the object for a triggered touch event</string>
-	<string name="LSLTipText_llDetectedTouchPos">vector llDetectedTouchPos(integer number)\nreturns the position touched for a triggered touch event</string>
-	<string name="LSLTipText_llDetectedTouchNormal">vector llDetectedTouchNormal(integer number)\nreturns the surface normal for a triggered touch event</string>
-	<string name="LSLTipText_llDetectedTouchBinormal">vector llDetectedTouchBinormal(integer number)\nreturns the surface binormal for a triggered touch event</string>
-	<string name="LSLTipText_llDetectedTouchST">vector llDetectedTouchST(integer number)\nreturns the s and t coordinates in the first two components of a vector, for a triggered touch event</string>
-	<string name="LSLTipText_llSHA1String">string llSHA1String(string sr)\nPerforms a SHA1 security Hash.  Returns a 40 character hex string.</string>
-	<string name="LSLTipText_llGetFreeURLs">integer llGetFreeURLs()\nreturns the available urls for the current script</string>
-	<string name="LSLTipText_llRequestURL">key llRequestURL()\nRequests one HTTP:// url for use by this object\nTriggers an http_server event with results.</string>
-	<string name="LSLTipText_llRequestSecureURL">key llRequestSecureURL()\nRequests one HTTPS:// (SSL) url for use by this object\nTriggers an http_server event with results.</string>
-	<string name="LSLTipText_llReleaseURL">llReleaseURL(string url)\nReleases the specified URL, it will no longer be usable.</string>
-	<string name="LSLTipText_llHTTPResponse">llHTTPResponse(key id, integer status, string body)\nResponds to request id with status and body.</string>
-	<string name="LSLTipText_llGetHTTPHeader">string llGetHTTPHeader(key id, string header)\nGet the value for header for request id.</string>
+	<string name="LSLTipText_llSin">
+float llSin(float theta)
+theta in radians
+	</string>
+	<string name="LSLTipText_llCos">
+float llCos(float theta)
+theta in radians
+	</string>
+	<string name="LSLTipText_llTan">
+float llTan(float theta)
+theta radians
+	</string>
+	<string name="LSLTipText_llAtan2">
+float llAtan2(float y, float x)
+	</string>
+	<string name="LSLTipText_llSqrt">
+float llSqrt(float val)
+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
+	</string>
+	<string name="LSLTipText_llAbs">
+integer llAbs(integer val)
+	</string>
+	<string name="LSLTipText_llFabs">
+float llFabs(float val)
+	</string>
+	<string name="LSLTipText_llFrand">
+float llFrand(float mag)
+returns random number in range [0,mag)
+	</string>
+	<string name="LSLTipText_llFloor">
+integer llFloor(float val)
+returns largest integer value &lt;= val
+	</string>
+	<string name="LSLTipText_llCeil">
+integer llCeil(float val)
+returns smallest integer value &gt;= val
+	</string>
+	<string name="LSLTipText_llRound">
+integer llRound(float val)
+returns val rounded to the nearest integer
+	</string>
+	<string name="LSLTipText_llVecMag">
+float llVecMag(vector v)
+returns the magnitude of v
+	</string>
+	<string name="LSLTipText_llVecNorm">
+vector llVecNorm(vector v)
+returns the v normalized
+	</string>
+	<string name="LSLTipText_llVecDist">
+float llVecDist(vector v1, vector 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
+	</string>
+	<string name="LSLTipText_llEuler2Rot">
+rotation llEuler2Rot(vector 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
+	</string>
+	<string name="LSLTipText_llRot2Fwd">
+vector llRot2Fwd(rotation q)
+returns the forward vector defined by q
+	</string>
+	<string name="LSLTipText_llRot2Left">
+vector llRot2Left(rotation q)
+returns the left vector defined by q
+	</string>
+	<string name="LSLTipText_llRot2Up">
+vector llRot2Up(rotation 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
+	</string>
+	<string name="LSLTipText_llWhisper">
+llWhisper(integer channel, string msg)
+whispers msg on channel
+	</string>
+	<string name="LSLTipText_llSay">
+llSay(integer channel, string msg)
+says msg on channel
+	</string>
+	<string name="LSLTipText_llShout">
+llShout(integer channel, string msg)
+shouts 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
+	</string>
+	<string name="LSLTipText_llListenControl">
+llListenControl(integer number, integer active)
+makes a listen event callback active or inactive
+	</string>
+	<string name="LSLTipText_llListenRemove">
+llListenRemove(integer number)
+removes listen event callback number
+	</string>
+	<string name="LSLTipText_llSensor">
+llSensor(string name, key id, integer type, float range, float arc)
+Performs a single scan 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)
+	</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
+	</string>
+	<string name="LSLTipText_llSensorRemove">
+llSensorRemove()
+removes sensor
+	</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)
+	</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)
+	</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)
+	</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)
+	</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)
+	</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)
+	</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)
+	</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)
+	</string>
+	<string name="LSLTipText_llDetectedGroup">
+integer llDetectedGroup(integer number)
+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
+	</string>
+	<string name="LSLTipText_llDie">
+llDie()
+deletes the object
+	</string>
+	<string name="LSLTipText_llGround">
+float llGround(vector v)
+returns the ground height below the object position + v
+	</string>
+	<string name="LSLTipText_llCloud">
+float llCloud(vector v)
+returns the cloud density at the object position + v
+	</string>
+	<string name="LSLTipText_llWind">
+vector llWind(vector v)
+returns the wind velocity at the object position + v
+	</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
+	</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)
+	</string>
+	<string name="LSLTipText_llSetScale">
+llSetScale(vector scale)
+sets the scale
+	</string>
+	<string name="LSLTipText_llGetScale">
+vector llGetScale()
+gets the scale
+	</string>
+	<string name="LSLTipText_llSetColor">
+llSetColor(vector color, integer face)
+sets the color
+	</string>
+	<string name="LSLTipText_llGetAlpha">
+float llGetAlpha(integer face)
+gets the alpha
+	</string>
+	<string name="LSLTipText_llSetAlpha">
+llSetAlpha(float alpha, integer face)
+sets the alpha
+	</string>
+	<string name="LSLTipText_llGetColor">
+vector llGetColor(integer face)
+gets the color
+	</string>
+	<string name="LSLTipText_llSetTexture">
+llSetTexture(string texture, integer face)
+sets the texture of face
+	</string>
+	<string name="LSLTipText_llScaleTexture">
+llScaleTexture(float scales, float scalet, integer face)
+sets the texture s, t scales for the chosen face
+	</string>
+	<string name="LSLTipText_llOffsetTexture">
+llOffsetTexture(float offsets, float offsett, integer face)
+sets the texture s, t offsets for the chosen face
+	</string>
+	<string name="LSLTipText_llRotateTexture">
+llRotateTexture(float rotation, integer 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)
+	</string>
+	<string name="LSLTipText_llSetPos">
+llSetPos(vector pos)
+sets the position (if the script isn&apos;t physical)
+	</string>
+	<string name="LSLTipText_llGetPos">
+vector llGetPos()
+gets the position (if the script isn&apos;t physical)
+	</string>
+	<string name="LSLTipText_llGetLocalPos">
+vector llGetLocalPos()
+gets the position relative to the root (if the script isn&apos;t physical)
+	</string>
+	<string name="LSLTipText_llSetRot">
+llSetRot(rotation rot)
+sets the rotation (if the script isn&apos;t physical)
+	</string>
+	<string name="LSLTipText_llGetRot">
+rotation llGetRot()
+gets the rotation (if the script isn&apos;t physical)
+	</string>
+	<string name="LSLTipText_llGetLocalRot">
+rotation llGetLocalRot()
+gets the rotation local to the root (if the script isn&apos;t physical)
+	</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)
+	</string>
+	<string name="LSLTipText_llGetForce">
+vector llGetForce()
+gets 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
+	</string>
+	<string name="LSLTipText_llTargetRemove">
+llTargetRemove(integer number)
+removes target number
+	</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
+	</string>
+	<string name="LSLTipText_llRotTargetRemove">
+llRotTargetRemove(integer number)
+removes rotational target number
+	</string>
+	<string name="LSLTipText_llMoveToTarget">
+llMoveToTarget(vector target, float tau)
+critically damp to target in tau seconds (if the script is physical)
+	</string>
+	<string name="LSLTipText_llStopMoveToTarget">
+llStopMoveToTarget()
+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)
+	</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)
+	</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)
+	</string>
+	<string name="LSLTipText_llGetTorque">
+vector llGetTorque()
+gets 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)
+	</string>
+	<string name="LSLTipText_llGetVel">
+vector llGetVel()
+gets the velocity
+	</string>
+	<string name="LSLTipText_llGetAccel">
+vector llGetAccel()
+gets the acceleration
+	</string>
+	<string name="LSLTipText_llGetOmega">
+vector llGetOmega()
+gets the omega
+	</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)
+	</string>
+	<string name="LSLTipText_llGetWallclock">
+float llGetWallclock()
+gets the time in seconds since midnight
+	</string>
+	<string name="LSLTipText_llGetTime">
+float llGetTime()
+gets the time in seconds since creation
+	</string>
+	<string name="LSLTipText_llResetTime">
+llResetTime()
+sets the time to zero
+	</string>
+	<string name="LSLTipText_llGetAndResetTime">
+float llGetAndResetTime()
+gets the time in seconds since creation and sets the time 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
+	</string>
+	<string name="LSLTipText_llPlaySound">
+llPlaySound(string sound, float volume)
+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)
+	</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
+	</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
+	</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
+	</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
+	</string>
+	<string name="LSLTipText_llStopSound">
+llStopSound()
+Stops currently attached sound
+	</string>
+	<string name="LSLTipText_llPreloadSound">
+llPreloadSound(string sound)
+preloads a sound on viewers within range
+	</string>
+	<string name="LSLTipText_llGetSubString">
+string llGetSubString(string src, integer start, integer end)
+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
+	</string>
+	<string name="LSLTipText_llInsertString">
+string llInsertString(string dst, integer position, string src)
+inserts src into dst at position and returns the result
+	</string>
+	<string name="LSLTipText_llToUpper">
+string llToUpper(string src)
+convert src to all upper case and returns the result
+	</string>
+	<string name="LSLTipText_llToLower">
+string llToLower(string src)
+convert src to all lower case and returns the result
+	</string>
+	<string name="LSLTipText_llGiveMoney">
+llGiveMoney(key destination, integer amount)
+transfer amount of money 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
+	</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
+	</string>
+	<string name="LSLTipText_llMakeSmoke">
+llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)
+Make 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
+	</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
+	</string>
+	<string name="LSLTipText_llLookAt">
+llLookAt(vector target, F32 strength, F32 damping)
+Cause object name to point it&apos;s forward axis towards target
+	</string>
+	<string name="LSLTipText_llStopLookAt">
+llStopLookAt()
+Stop causing object name to point at a target
+	</string>
+	<string name="LSLTipText_llSetTimerEvent">
+llSetTimerEvent(float sec)
+Cause the timer event to be triggered every sec seconds
+	</string>
+	<string name="LSLTipText_llSleep">
+llSleep(float sec)
+Put script to sleep for sec seconds
+	</string>
+	<string name="LSLTipText_llGetMass">
+float llGetMass()
+Get the mass of task name that 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
+	</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.
+	</string>
+	<string name="LSLTipText_llReleaseControls">
+llReleaseControls()
+Stop taking inputs
+	</string>
+	<string name="LSLTipText_llAttachToAvatar">
+llAttachToAvatar(integer attachment)
+Attach to avatar task has permissions for at point attachment
+	</string>
+	<string name="LSLTipText_llDetachFromAvatar">
+llDetachFromAvatar()
+Drop off of avatar
+	</string>
+	<string name="LSLTipText_llTakeCamera">
+llTakeCamera(key avatar)
+Move avatar&apos;s viewpoint to task
+	</string>
+	<string name="LSLTipText_llReleaseCamera">
+llReleaseCamera(key avatar)
+Return camera to agent
+	</string>
+	<string name="LSLTipText_llGetOwner">
+key llGetOwner()
+Returns the owner of the task
+	</string>
+	<string name="LSLTipText_llInstantMessage">
+llInstantMessage(key user, string message)
+IMs message to the user
+	</string>
+	<string name="LSLTipText_llEmail">
+llEmail(string address, string subject, string message)
+Sends email to address with 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)
+	</string>
+	<string name="LSLTipText_llGetKey">
+key llGetKey()
+Get the key for the task 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)
+	</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)
+	</string>
+	<string name="LSLTipText_llStopHover">
+llStopHover()
+Stop hovering to a height
+	</string>
+	<string name="LSLTipText_llMinEventDelay">
+llMinEventDelay(float delay)
+Set the minimum time between events being handled
+	</string>
+	<string name="LSLTipText_llSoundPreload">
+llSoundPreload(string sound)
+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
+	</string>
+	<string name="LSLTipText_llStringLength">
+integer llStringLength(string str)
+Returns the length of string
+	</string>
+	<string name="LSLTipText_llStartAnimation">
+llStartAnimation(string anim)
+Start animation anim for agent that owns object
+	</string>
+	<string name="LSLTipText_llStopAnimation">
+llStopAnimation(string anim)
+Stop animation anim for agent that owns object
+	</string>
+	<string name="LSLTipText_llPointAt">
+llPointAt(vector pos)
+Make agent that owns object point at pos
+	</string>
+	<string name="LSLTipText_llStopPointAt">
+llStopPointAt()
+Stop agent that owns object pointing
+	</string>
+	<string name="LSLTipText_llTargetOmega">
+llTargetOmega(vector axis, float spinrate, float gain)
+Attempt to spin at spinrate with strength gain
+	</string>
+	<string name="LSLTipText_llGetStartParameter">
+integer llGetStartParameter()
+Get's the start paramter passed to llRezObject
+	</string>
+	<string name="LSLTipText_llGodLikeRezObject">
+llGodLikeRezObject(key inventory, vector pos)
+rez directly off of a UUID if owner has dog-bit set
+	</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)
+	</string>
+	<string name="LSLTipText_llGetPermissionsKey">
+key llGetPermissionsKey()
+Return agent that permissions are enabled for.  NULL_KEY if not enabled
+	</string>
+	<string name="LSLTipText_llGetPermissions">
+integer llGetPermissions()
+return what permissions have been enabled
+	</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)
+	</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
+	</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
+	</string>
+	<string name="LSLTipText_llBreakLink">
+llBreakLink(integer linknum)
+Delinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)
+	</string>
+	<string name="LSLTipText_llBreakAllLinks">
+llBreakAllLinks()
+Delinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)
+	</string>
+	<string name="LSLTipText_llGetLinkKey">
+key llGetLinkKey(integer linknum)
+Get the key of linknumber in link set
+	</string>
+	<string name="LSLTipText_llGetLinkName">
+string llGetLinkName(integer linknum)
+Get the name of linknumber in 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
+	</string>
+	<string name="LSLTipText_llGetInventoryName">
+string llGetInventoryName(integer type, integer number)
+Get the name of the inventory item number of type
+	</string>
+	<string name="LSLTipText_llSetScriptState">
+llSetScriptState(string name, integer run)
+Control the state of a script name.
+	</string>
+	<string name="LSLTipText_llGetEnergy">
+float llGetEnergy()
+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
+	</string>
+	<string name="LSLTipText_llRemoveInventory">
+llRemoveInventory(string inventory)
+Remove the named inventory item
+	</string>
+	<string name="LSLTipText_llSetText">
+llSetText(string text, vector color, float alpha)
+Set text floating over object
+	</string>
+	<string name="LSLTipText_llWater">
+float llWater(vector v)
+returns the water height below the object position + v
+	</string>
+	<string name="LSLTipText_llPassTouches">
+llPassTouches(integer pass)
+if pass == TRUE, touches are passed from children on to parents (default is FALSE)
+	</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
+	</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
+	</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.
+	</string>
+	<string name="LSLTipText_llTeleportAgentHome">
+llTeleportAgentHome(key id)
+Teleports agent on owner's land to agent's home location
+	</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)
+	</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)
+	</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)
+	</string>
+	<string name="LSLTipText_llGetAnimation">
+string llGetAnimation(key id)
+Get the currently playing locomotion animation for avatar id
+	</string>
+	<string name="LSLTipText_llResetScript">
+llResetScript()
+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)
+	</string>
+	<string name="LSLTipText_llPushObject">
+llPushObject(key id, vector impulse, vector ang_impulse, integer local)
+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)
+	</string>
+	<string name="LSLTipText_llGetScriptName">
+llGetScriptName()
+Returns the script name
+	</string>
+	<string name="LSLTipText_llGetNumberOfSides">
+integer llGetNumberOfSides()
+Returns the number of sides
+	</string>
+	<string name="LSLTipText_llAxisAngle2Rot">
+rotation llAxisAngle2Rot(vector axis, float angle)
+Returns the rotation generated angle about axis
+	</string>
+	<string name="LSLTipText_llRot2Axis">
+vector llRot2Axis(rotation rot)
+Returns the rotation axis represented by rot
+	</string>
+	<string name="LSLTipText_llRot2Angle">
+float llRot2Angle(rotation rot)
+Returns the rotation angle represented by rot
+	</string>
+	<string name="LSLTipText_llAcos">
+float llAcos(float val)
+Returns the arccosine in radians of val
+	</string>
+	<string name="LSLTipText_llAsin">
+float llAsin(float val)
+Returns the arcsine in radians of val
+	</string>
+	<string name="LSLTipText_llAngleBetween">
+float llAngleBetween(rotation a, rotation b)
+Returns angle between rotation a and b
+	</string>
+	<string name="LSLTipText_llGetInventoryKey">
+key llGetInventoryKey(string name)
+Returns the key 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
+	</string>
+	<string name="LSLTipText_llGetSunDirection">
+vector llGetSunDirection()
+Returns the sun direction on the simulator
+	</string>
+	<string name="LSLTipText_llGetTextureOffset">
+vector llGetTextureOffset(integer side)
+Returns the texture offset of side in the x and y components of a vector
+	</string>
+	<string name="LSLTipText_llGetTextureScale">
+vector llGetTextureScale(integer side)
+Returns the texture scale of side in the x and y components of a vector
+	</string>
+	<string name="LSLTipText_llGetTextureRot">
+float llGetTextureRot(integer side)
+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)
+	</string>
+	<string name="LSLTipText_llGetOwnerKey">
+key llGetOwnerKey(key id)
+Find the owner of id
+	</string>
+	<string name="LSLTipText_llGetCenterOfMass">
+vector llGetCenterOfMass()
+Get the object'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.
+	</string>
+	<string name="LSLTipText_llGetListLength">
+integer llGetListLength(list src)
+Get 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
+	</string>
+	<string name="LSLTipText_llList2Float">
+float llList2Float(list src, integer index)
+Copy 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
+	</string>
+	<string name="LSLTipText_llList2Key">
+key llList2Key(list src, integer index)
+Copy 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
+	</string>
+	<string name="LSLTipText_llList2Rot">
+rotation llList2Rot(list src, integer index)
+Copy 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
+	</string>
+	<string name="LSLTipText_llDeleteSubList">
+list llDeleteSubList(list src, integer start, integer end)
+Remove the slice from the list and return the remainder
+	</string>
+	<string name="LSLTipText_llGetListEntryType">
+integer llGetListEntryType(list src, integer index)
+Returns the type of the index entry in the list
+(TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list)
+	</string>
+	<string name="LSLTipText_llList2CSV">
+string llList2CSV(list src)
+Create 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
+	</string>
+	<string name="LSLTipText_llListRandomize">
+list llListRandomize(list src, integer stride)
+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
+	</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
+	</string>
+	<string name="LSLTipText_llListInsertList">
+list llListInsertList(list dest, list src, integer start)
+Inserts src into dest 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
+	</string>
+	<string name="LSLTipText_llGetObjectName">
+string llGetObjectName()
+Returns the name of the object script is attached to
+	</string>
+	<string name="LSLTipText_llSetObjectName">
+llSetObjectName(string name)
+Sets the objects name
+	</string>
+	<string name="LSLTipText_llGetDate">
+string llGetDate()
+Gets the date as 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)
+	</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 and/or AGENT_IN_AIR.
+	</string>
+	<string name="LSLTipText_llAdjustSoundVolume">
+llAdjustSoundVolume(float volume)
+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)
+	</string>
+	<string name="LSLTipText_llSetSoundRadius">
+llSetSoundRadius(float radius)
+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
+	</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
+	</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
+	</string>
+	<string name="LSLTipText_llEjectFromLand">
+llEjectFromLand(key pest)
+Ejects pest from land that you own
+	</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)
+	</string>
+	<string name="LSLTipText_llOverMyLand">
+integer llOverMyLand(key id)
+Returns TRUE if id is over land owner of object owns, FALSE otherwise
+	</string>
+	<string name="LSLTipText_llGetLandOwnerAt">
+key llGetLandOwnerAt(vector pos)
+Returns the key of the land owner, NULL_KEY if public
+	</string>
+	<string name="LSLTipText_llGetNotecardLine">
+key llGetNotecardLine(string name, integer line)
+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
+	</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
+	</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
+	</string>
+	<string name="LSLTipText_llGroundSlope">
+vector llGroundSlope(vector v)
+returns the ground slope below the object position + v
+	</string>
+	<string name="LSLTipText_llGroundNormal">
+vector llGroundNormal(vector v)
+returns the ground normal below the object position + v
+	</string>
+	<string name="LSLTipText_llGroundContour">
+vector llGroundCountour(vector v)
+returns the ground contour below the object position + v
+	</string>
+	<string name="LSLTipText_llGetAttached">
+integer llGetAttached()
+returns the object attachment point or 0 if not attached
+	</string>
+	<string name="LSLTipText_llGetFreeMemory">
+integer llGetFreeMemory()
+returns the available heap space for the current script
+	</string>
+	<string name="LSLTipText_llGetRegionName">
+string llGetRegionName()
+returns the current region name
+	</string>
+	<string name="LSLTipText_llGetRegionTimeDilation">
+float llGetRegionTimeDilation()
+returns the current time dilation as a float between 0 and 1
+	</string>
+	<string name="LSLTipText_llGetRegionFPS">
+float llGetRegionFPS()
+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.
+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)
+	</string>
+	<string name="LSLTipText_llGiveInventoryList">
+llGiveInventoryList(key destination, string category, list inventory)
+Give inventory to destination in a new category
+	</string>
+	<string name="LSLTipText_llSetVehicleType">
+llSetVehicleType(integer type)
+sets vehicle to one of the default types
+	</string>
+	<string name="LSLTipText_llSetVehicleFloatParam">
+llSetVehicleFloatParam(integer param, float value)
+sets the specified vehicle float parameter
+	</string>
+	<string name="LSLTipText_llSetVehicleVectorParam">
+llSetVehicleVectorParam(integer param, vector vec)
+sets the specified vehicle vector parameter
+	</string>
+	<string name="LSLTipText_llSetVehicleRotationParam">
+llSetVehicleVectorParam(integer param, rotation rot)
+sets the specified vehicle rotation parameter
+	</string>
+	<string name="LSLTipText_llSetVehicleFlags">
+llSetVehicleFlags(integer flags)
+sets the enabled bits in 'flags'
+	</string>
+	<string name="LSLTipText_llRemoveVehicleFlags">
+llRemoveVehicleFlags(integer flags)
+removes the enabled bits in 'flags'
+	</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)
+	</string>
+	<string name="LSLTipText_llAvatarOnSitTarget">
+key llAvatarOnSitTarget()
+If an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise
+	</string>
+	<string name="LSLTipText_llAddToLandPassList">
+llAddToLandPassList(key avatar, float hours)
+Add avatar to the land pass list for hours
+	</string>
+	<string name="LSLTipText_llSetTouchText">
+llSetTouchText(string text)
+Displays text in pie menu that acts as a touch
+	</string>
+	<string name="LSLTipText_llSetSitText">
+llSetSitText(string text)
+Displays text rather than sit in 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
+	</string>
+	<string name="LSLTipText_llSetCameraAtOffset">
+llSetCameraAtOffset(vector offset)
+Sets the camera at offset used in this object if an avatar sits on it
+	</string>
+	<string name="LSLTipText_llDumpList2String">
+string llDumpList2String(list src, string separator)
+Write the list out in a single string using separator between values
+	</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
+	</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.
+	</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.
+	</string>
+	<string name="LSLTipText_llResetOtherScript">
+llResetOtherScript(string name)
+Resets script name
+	</string>
+	<string name="LSLTipText_llGetScriptState">
+integer llGetScriptState(string name)
+Resets TRUE if script name is running
+	</string>
+	<string name="LSLTipText_llRemoteLoadScript">
+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.
+	</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.
+	</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.
+	</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.
+	</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
+	</string>
+	<string name="LSLTipText_llCloseRemoteDataChannel">
+llCloseRemoteDataChannel(key 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.
+	</string>
+	<string name="LSLTipText_llSetPrimitiveParams">
+llSetPrimitiveParams(list rules)
+Set primitive parameters based on rules.
+	</string>
+	<string name="LSLTipText_llStringToBase64">
+string llStringToBase64(string str)
+Converts a string to the Base 64 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.
+	</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.
+	</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.
+	</string>
+	<string name="LSLTipText_llLog10">
+float llLog10(float val)
+Returns the base 10 log of val if val &gt; 0, otherwise returns 0.
+	</string>
+	<string name="LSLTipText_llLog">
+float llLog(float val)
+Returns the base e log of val if val &gt; 0, otherwise returns 0.
+	</string>
+	<string name="LSLTipText_llGetAnimationList">
+list llGetAnimationList(key id)
+Gets a list of all playing animations for avatar id
+	</string>
+	<string name="LSLTipText_llSetParcelMusicURL">
+llSetParcelMusicURL(string url)
+Sets the streaming audio URL for the parcel 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
+	</string>
+	<string name="LSLTipText_llGetRootRotation">
+rotation llGetRootRotation()
+Gets the global rotation of the root object of the object script is attached to
+	</string>
+	<string name="LSLTipText_llGetObjectDesc">
+string llGetObjectDesc()
+Returns the description of the object the script is attached to
+	</string>
+	<string name="LSLTipText_llSetObjectDesc">
+llSetObjectDesc(string name)
+Sets the object's description
+	</string>
+	<string name="LSLTipText_llGetCreator">
+key llGetCreator()
+Returns the creator of the object
+	</string>
+	<string name="LSLTipText_llGetTimestamp">
+string llGetTimestamp()
+Gets the timestamp 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
+	</string>
+	<string name="LSLTipText_llGetNumberOfPrims">
+integer llGetNumberOfPrims()
+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)
+	</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 ]
+	</string>
+	<string name="LSLTipText_llGetGeometricCenter">
+vector llGetGeometricCenter()
+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.
+	</string>
+	<string name="LSLTipText_llIntegerToBase64">
+string llIntegerToBase64(integer number)
+Big endian encode of of integer as a Base64 string.
+	</string>
+	<string name="LSLTipText_llBase64ToInteger">
+integer llBase64ToInteger(string str)
+Big endian decode of a Base64 string into an integer.
+	</string>
+	<string name="LSLTipText_llGetGMTclock">
+float llGetGMTclock()
+Gets the time in seconds since midnight in 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)
+	</string>
+	<string name="LSLTipText_llSetLocalRot">
+llSetLocalRot(rotation rot)
+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.
+	</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
+	</string>
+	<string name="LSLTipText_llGetObjectPermMask">
+integer llGetObjectPermMask(integer mask)
+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.
+	</string>
+	<string name="LSLTipText_llGetInventoryPermMask">
+integer llGetInventoryPermMask(string item, integer mask)
+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.
+	</string>
+	<string name="LSLTipText_llGetInventoryCreator">
+key llGetInventoryCreator(string item)
+Returns the 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)
+	</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
+	</string>
+	<string name="LSLTipText_llForceMouselook">
+llForceMouselook(integer mouselook)
+If mouselook is TRUE any avatar that sits on this object is forced into mouselook mode
+	</string>
+	<string name="LSLTipText_llGetObjectMass">
+float llGetObjectMass(key id)
+Get the mass of the object with key id
+	</string>
+	<string name="LSLTipText_llListReplaceList">
+list llListReplaceList(list dest, list src, integer start, integer end)
+Replaces start through end of dest with src.
+	</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.
+	</string>
+	<string name="LSLTipText_llParcelMediaCommandList">
+llParcelMediaCommandList(list command)
+Sends a list of commands, some with arguments, to a parcel.
+	</string>
+	<string name="LSLTipText_llParcelMediaQuery">
+list llParcelMediaQuery(list query)
+Sends a list of queries, returns a list of results.
+	</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).
+	</string>
+	<string name="LSLTipText_llGetInventoryType">
+integer llGetInventoryType(string name)
+Returns the type of the inventory name
+	</string>
+	<string name="LSLTipText_llSetPayPrice">
+llSetPayPrice(integer price, list quick_pay_buttons)
+Sets the default amount when someone chooses to pay this object.
+	</string>
+	<string name="LSLTipText_llGetCameraPos">
+vector llGetCameraPos()
+Gets current camera position for agent task has permissions for.
+	</string>
+	<string name="LSLTipText_llGetCameraRot">
+rotation llGetCameraRot()
+Gets current camera orientation for agent 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.
+	</string>
+	<string name="LSLTipText_llRefreshPrimURL">
+llRefreshPrimURL()
+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.
+	</string>
+	<string name="LSLTipText_llUnescapeURL">
+string llUnescapeURL(string url)
+Returns and 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.
+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
+	</string>
+	<string name="LSLTipText_llRemoveFromLandPassList">
+llRemoveFromLandPassList(key avatar)
+Remove avatar from the land pass list
+	</string>
+	<string name="LSLTipText_llRemoveFromLandBanList">
+llRemoveFromLandBanList(key avatar)
+Remove avatar from the land ban list
+	</string>
+	<string name="LSLTipText_llSetCameraParams">
+llSetCameraParams(list rules)
+Sets multiple camera parameters at once.
+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.
+	</string>
+	<string name="LSLTipText_llListStatistics">
+float llListStatistics(integer operation, list l)
+Perform statistical aggregate functions on list l 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.
+	</string>
+	<string name="LSLTipText_llGetParcelFlags">
+integer llGetParcelFlags(vector pos)
+Get the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.
+	</string>
+	<string name="LSLTipText_llGetRegionFlags">
+integer llGetRegionFlags()
+Get 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.
+	</string>
+	<string name="LSLTipText_llHTTPRequest">
+llHTTPRequest(string url, list parameters, string body)
+Send an HTTP request.
+	</string>
+	<string name="LSLTipText_llResetLandBanList">
+llResetLandBanList()
+Removes all residents from the land ban list.
+	</string>
+	<string name="LSLTipText_llResetLandPassList">
+llResetLandPassList()
+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.
+	</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.
+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.
+	</string>
+	<string name="LSLTipText_llGetParcelMaxPrims">
+integer llGetParcelMaxPrims(vector pos, integer sim_wide)
+Gets 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.
+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.
+	</string>
+	<string name="LSLTipText_llSetLinkTexture">
+llSetLinkTexture(integer link_pos, string texture, integer face)
+Sets the texture of face for link_pos
+	</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.
+	</string>
+	<string name="LSLTipText_llRegionSay">
+llRegionSay(integer channel, string msg)
+broadcasts msg to entire region on channel (not 0.)
+	</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.
+	</string>
+	<string name="LSLTipText_llSetClickAction">
+llSetClickAction(integer action)
+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
+	</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.
+	</string>
+	<string name="LSLTipText_llGetAgentLanguage">
+string llGetAgentLanguage(key id)
+Gets the agents preferred language..
+	</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
+	</string>
+	<string name="LSLTipText_llDetectedTouchFace">
+integer llDetectedTouchFace(integer number)
+returns the index of the face on the object for a triggered touch event
+	</string>
+	<string name="LSLTipText_llDetectedTouchPos">
+vector llDetectedTouchPos(integer number)
+returns the position touched for a triggered touch event
+	</string>
+	<string name="LSLTipText_llDetectedTouchNormal">
+vector llDetectedTouchNormal(integer number)
+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
+	</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
+	</string>
+	<string name="LSLTipText_llSHA1String">
+string llSHA1String(string sr)
+Performs a SHA1 security Hash.  Returns a 40 character hex string.
+	</string>
+	<string name="LSLTipText_llGetFreeURLs">
+integer llGetFreeURLs()
+returns the 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.
+	</string>
+	<string name="LSLTipText_llRequestSecureURL">
+key llRequestSecureURL()
+Requests one HTTPS:// (SSL) url for use by this object
+Triggers an http_server event with results.
+	</string>
+	<string name="LSLTipText_llReleaseURL">
+llReleaseURL(string url)
+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>
+	<string name="LSLTipText_llGetHTTPHeader">
+string llGetHTTPHeader(key id, string header)
+Get the value for header for request id.
+	</string>
 	
 	<!-- Avatar busy/away mode -->
 	<string name="AvatarSetNotAway">Set Not Away</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eabacbecb25f31573b9b2385ef6678087fcd8ed4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<accordion_tab 
+    header_collapse_img="accordion_collapsed.tga" 
+    header_collapse_img_pressed="accordion_collapsed.tga" 
+    header_expand_img="accordion_expanded.tga"
+    header_expand_img_pressed="accordion_expanded.tga" />
diff --git a/indra/newview/skins/default/xui/en/widgets/list.xml b/indra/newview/skins/default/xui/en/widgets/list.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4a59716464a682200808b804b6f51f2a2fc6f342
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/list.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<list
+ allow_select="true"
+ bg_opaque_color="PanelFocusBackgroundColor"
+ bg_alpha_color="PanelDefaultBackgroundColor"
+ background_visible="false"
+ background_opaque="false"
+ item_pad="5"
+ keep_one_selected="true"
+ multi_select="false" />
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index 8f4d0edf953947b02d8133d4c6203c37f42c04ef..297a3762f6c419d1f119edd3d912e8fa306b9363 100644
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -43,7 +43,7 @@
                           label=""
                           pad_right="0"
                           tool_tip="My Location History"/>
-  <combo_list bg_writeable_color="MenuDefaultBgColor"/>
+  <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"/>
   <combo_editor name="Combo Text Entry"
                 text_pad_left="20"
                 select_on_focus="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
new file mode 100644
index 0000000000000000000000000000000000000000..1d43b25f1d4696a7cfe43ae73113bc9420982132
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<search_combo_box
+ allow_text_entry="true"
+ list_position="BELOW"
+ show_text_as_tentative="false"
+ dropdown_button_visible="false"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active">
+ <combo_editor
+  select_on_focus="true"
+  text_pad_left="20" 
+  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" />
+ <search_button label=""
+  top_pad="4"
+  left_pad="4" 
+  width="13"
+  height="13" 
+  image_unselected="Search"
+  image_selected="Search" />
+</search_combo_box>
\ No newline at end of file
diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp
index 27ab127772fe5504852d0d3f0fd04ef48b12fc3c..34f3530308113a5078d41340bbbd2d96802fa78e 100755
--- a/indra/test/llsdmessagebuilder_tut.cpp
+++ b/indra/test/llsdmessagebuilder_tut.cpp
@@ -353,7 +353,7 @@ namespace tut
 	{
 	  char binData[] = "abcdefghijklmnop";
 
-	  addValue(messageBlockData, "testBinData", &binData, MVT_FIXED, sizeof(binData));
+	  addValue(messageBlockData, (char *)"testBinData", &binData, MVT_FIXED, sizeof(binData));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -393,7 +393,7 @@ namespace tut
 	{
 	  U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts
 
-	  addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2);
+	  addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2);
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -413,7 +413,7 @@ namespace tut
 	{
 	  U32 binData[] = {9,8,7,6,5,4,3,2,1};
 
-	  addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4);
+	  addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4);
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -433,7 +433,7 @@ namespace tut
 	{
 	  U8 data = 0xa5;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_U8, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U8, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -450,7 +450,7 @@ namespace tut
 	{
 	  U16 data = 0xa55a;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_U16, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -467,7 +467,7 @@ namespace tut
 	{
 	  U32 data = 0xa55a7117;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_U32, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U32, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -483,7 +483,7 @@ namespace tut
 	void LLSDMessageBuilderTestObject::test<27>()
 	{
 	  U64 data = U64L(0xa55a711711223344);
-	  addValue(messageBlockData, "testBinData", &data, MVT_U64, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U64, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -500,7 +500,7 @@ namespace tut
 	{
 	  S8 data = -31;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_S8, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_S8, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -517,7 +517,7 @@ namespace tut
 	{
 	  S16 data = -31;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_S16, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -534,7 +534,7 @@ namespace tut
 	{
 	  S32 data = -3100;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_S32, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_S32, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -551,7 +551,7 @@ namespace tut
 	{
 	  S64 data = -31003100;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_S64, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_S64, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -568,7 +568,7 @@ namespace tut
 	{
 	  F32 data = 1234.1234f;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_F32, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_F32, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -585,7 +585,7 @@ namespace tut
 	{
 	  F64 data = 1234.1234;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_F64, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_F64, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -602,7 +602,7 @@ namespace tut
 	{
 	  LLVector3 data(1,2,3);
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector3, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -619,7 +619,7 @@ namespace tut
 	{
 	  LLVector3d data(1,2,3);
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector3d, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3d, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -637,7 +637,7 @@ namespace tut
 	  LLVector4 data(1,2,3,4);
 	  LLSD v = ll_sd_from_vector4(data);
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector4, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector4, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -657,7 +657,7 @@ namespace tut
 	  //we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16.
 	  LLVector3 vec = data.packToVector3();
 
-	  addValue(messageBlockData, "testBinData", &vec, MVT_LLQuaternion, sizeof(vec));
+	  addValue(messageBlockData, (char *)"testBinData", &vec, MVT_LLQuaternion, sizeof(vec));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -674,7 +674,7 @@ namespace tut
 	{
 	  LLUUID data("01234567-0123-0123-0123-234567abcdef");
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_LLUUID, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLUUID, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -696,8 +696,8 @@ namespace tut
 
 	  LLMsgData* md = new LLMsgData("testMessage");
 	  LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0);
-	  addValue(mbd, "testBoolFalse", &valueFalse, MVT_BOOL, sizeof(BOOL));
-	  addValue(mbd, "testBoolTrue", &valueTrue, MVT_BOOL, sizeof(BOOL));
+	  addValue(mbd, (char *)"testBoolFalse", &valueFalse, MVT_BOOL, sizeof(BOOL));
+	  addValue(mbd, (char *)"testBoolTrue", &valueTrue, MVT_BOOL, sizeof(BOOL));
 	  md->addBlock(mbd);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -715,7 +715,7 @@ namespace tut
 	  U32 data(0xff887766);
 	  LLSD v = ll_sd_from_ipaddr(data);
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_IP_ADDR, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_ADDR, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -732,7 +732,7 @@ namespace tut
 	{
 	  U16 data = 0xff88;
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_IP_PORT, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_PORT, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -749,7 +749,7 @@ namespace tut
 	{
 	  U16 data[3] = {0,1,2};
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_U16Vec3, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Vec3, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -769,7 +769,7 @@ namespace tut
 	{
 	  U16 data[4] = {0,1,2,4};
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_U16Quat, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Quat, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
@@ -789,7 +789,7 @@ namespace tut
 	{
 	  S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18};
 
-	  addValue(messageBlockData, "testBinData", &data, MVT_S16Array, sizeof(data));
+	  addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16Array, sizeof(data));
 	  messageData->addBlock(messageBlockData);
 	  LLSDMessageBuilder builder = defaultBuilder();
 	  
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index f668867a02ed543c5190a49a686a879d0eddc3e1..7869763302f30d5fa67c460e7261f2a8209897c8 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -283,7 +283,7 @@ void LLMediaPluginTest::bindTexture(GLuint texture, GLint row_length, GLint alig
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-bool LLMediaPluginTest::checkGLError(char *name)
+bool LLMediaPluginTest::checkGLError(const char *name)
 {
 	bool result = false;
 	GLenum error = glGetError();
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.h b/indra/test_apps/llplugintest/llmediaplugintest.h
index 2d0ba0e3f67926091d689ac728c19bfb11c4a1c3..095a2ea3b313da878e0b786973223729a20a31af 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.h
+++ b/indra/test_apps/llplugintest/llmediaplugintest.h
@@ -87,7 +87,7 @@ class LLMediaPluginTest : public LLPluginClassMediaOwner
 		void mouseMove( int x, int y );
 
 		void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1);
-		bool checkGLError(char *name = "OpenGL");
+		bool checkGLError(const char *name = "OpenGL");
 		void drawGeometry( int panel );
 		void startPanelHighlight( float red, float green, float blue, float line_width );
 		void endPanelHighlight();