diff --git a/.hgtags b/.hgtags
index 07fdce592b07beb8ce6a4e1eefb0dc058e1ce52b..a4fb6ce9f80c89f13d812b8466a457d6d6dc5d24 100755
--- a/.hgtags
+++ b/.hgtags
@@ -552,3 +552,4 @@ ec09daf1899c1c01c4ba0ba950fae572f2a612a8 6.2.2-release
 ab2ec5c5423b277d23fd0511ce50c15123ff2e03 6.2.3-release
 67297f9902857e357570c44722ad84de3aff974e 6.2.4-release
 9777aec6dc4a30a24537297ac040861ce16b82ae 6.3.0-release
+ece699718f163921717bb95a6131e94af4c4138f 6.3.1-release
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 466dffded7214dd9769bd9fb58d6793cfdd8e7cf..0c68ae31002b9717e4962e0403196fca84868d89 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1073,6 +1073,7 @@ Nicky Dasmijn
 	MAINT-6665
 	SL-10291
 	SL-10293
+	SL-11061
 Nicky Perian
 	OPEN-1
 	STORM-1087
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 6c20a813bad182415bf5ca7665a1055c9bf0717a..62a8f3f003e8e0c19580eef1590c29d4e3302090 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -3,8 +3,8 @@
 # cmake_minimum_required should appear before any
 # other commands to guarantee full compatibility
 # with the version specified
-## prior to 3.4, the Windows manifest handling was missing
-cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
+## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support
+cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
 
 set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
     "The root project/makefile/solution name. Defaults to SecondLife.")
@@ -83,6 +83,12 @@ add_dependencies(viewer secondlife-bin)
 
 add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
 
+# sets the 'startup project' for debugging from visual studio.
+set_property(
+    DIRECTORY ${VIEWER_PREFIX}
+    PROPERTY VS_STARTUP_PROJECT secondlife-bin
+    )
+
 if (LL_TESTS)
   # Define after the custom targets are created so
   # individual apps can add themselves as dependencies
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 40fc706a9908b02a80bc4f1eb4ef0edd9192a951..03da30649a1c87033bdb40e6f326203bd3f0f326 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -151,6 +151,8 @@ endif (LINUX)
 
 
 if (DARWIN)
+  # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default
+  set(CLANG_DISABLE_FATAL_WARNINGS OFF)
   set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
   set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations")
diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h
index 6b22a2cb5997996744613292f5f46bde7d33625d..7372765075414405230df4a6b4dab20ada61b894 100644
--- a/indra/llaudio/llvorbisencode.h
+++ b/indra/llaudio/llvorbisencode.h
@@ -40,7 +40,7 @@ const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE        = 9; // unsupported word size
 const S32 LLVORBISENC_CLIP_TOO_LONG                = 10; // source file is too long
 const S32 LLVORBISENC_CHUNK_SIZE_ERR               = 11; // chunk size is wrong
 
-const F32 LLVORBIS_CLIP_MAX_TIME                               = 10.0f;
+const F32 LLVORBIS_CLIP_MAX_TIME                               = 30.0f;
 const U8  LLVORBIS_CLIP_MAX_CHANNELS                   = 2;
 const U32 LLVORBIS_CLIP_SAMPLE_RATE                            = 44100;
 const U32 LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL        = (U32)(LLVORBIS_CLIP_MAX_TIME * LLVORBIS_CLIP_SAMPLE_RATE);
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 30bec3a6f89ad30985f852ce57d85ecacdfc41d9..b619a9e48c55796693f4937797ff36f3cc64cc19 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1735,7 +1735,8 @@ bool LLStringUtilBase<T>::startsWith(
 	const string_type& substr)
 {
 	if(string.empty() || (substr.empty())) return false;
-	if(0 == string.find(substr)) return true;
+	if (substr.length() > string.length()) return false;
+	if (0 == string.compare(0, substr.length(), substr)) return true;
 	return false;
 }
 
@@ -1746,9 +1747,11 @@ bool LLStringUtilBase<T>::endsWith(
 	const string_type& substr)
 {
 	if(string.empty() || (substr.empty())) return false;
-	std::string::size_type idx = string.rfind(substr);
-	if(std::string::npos == idx) return false;
-	return (idx == (string.size() - substr.size()));
+	size_t sub_len = substr.length();
+	size_t str_len = string.length();
+	if (sub_len > str_len) return false;
+	if (0 == string.compare(str_len - sub_len, sub_len, substr)) return true;
+	return false;
 }
 
 // static
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 758b98e14390c7df48ba3e624940f71586d789f6..9942bc0cf8803eaaf8cbc61342d3827df8106fed 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -173,6 +173,19 @@ namespace
 			"-._~";
 		return s;
 	}
+	const std::string path()
+	{
+		static const std::string s =
+			"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+			"abcdefghijklmnopqrstuvwxyz"
+			"0123456789"
+			"$-_.+"
+			"!*'(),"
+			"{}|\\^~[]`"
+			"<>#%"
+			";/?:@&=";
+		return s;
+	}
 	const std::string sub_delims()
 	{
 		static const std::string s = "!$&'()*+,;=";
@@ -187,6 +200,12 @@ namespace
 		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,"); }	 // sub_delims - "&;=" + ":@"
 	std::string escapeQueryValue(const std::string& s)
 		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); }	// sub_delims - "&;" + ":@"
+	std::string escapeUriQuery(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + ":@?&$;*+=%/"); }
+	std::string escapeUriData(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + "%"); }
+	std::string escapeUriPath(const std::string& s)
+		{ return LLURI::escape(s, path()); }
 }
 
 //static
@@ -202,6 +221,85 @@ std::string LLURI::escape(const std::string& str)
 	return escape(str, default_allowed, true);
 }
 
+//static
+std::string LLURI::escapePathAndData(const std::string &str)
+{
+    std::string result;
+
+    const std::string data_marker = "data:";
+    if (str.compare(0, data_marker.length(), data_marker) == 0)
+    {
+        // This is not url, but data, data part needs to be properly escaped
+        // data part is separated by ',' from header. Minimal data uri is "data:,"
+        // See "data URI scheme"
+        size_t separator = str.find(',');
+        if (separator != std::string::npos)
+        {
+            size_t header_size = separator + 1;
+            std::string header = str.substr(0, header_size);
+            // base64 is url-safe
+            if (header.find("base64") != std::string::npos)
+            {
+                // assume url-safe data
+                result = str;
+            }
+            else
+            {
+                std::string data = str.substr(header_size, str.length() - header_size);
+
+                // Notes: File can be partially pre-escaped, that's why escaping ignores '%'
+                // It somewhat limits user from displaying strings like "%20" in text
+                // but that's how viewer worked for a while and user can double-escape it
+
+
+                // Header doesn't need escaping
+                result = header + escapeUriData(data);
+            }
+        }
+    }
+    else
+    {
+        // try processing it as path with query separator
+        // The query component is indicated by the first question
+        // mark("?") character and terminated by a number sign("#")
+        size_t delim_pos = str.find('?');
+        if (delim_pos == std::string::npos)
+        {
+            // alternate separator
+            delim_pos = str.find(';');
+        }
+
+        if (delim_pos != std::string::npos)
+        {
+            size_t path_size = delim_pos + 1;
+            std::string query;
+            std::string fragment;
+
+            size_t fragment_pos = str.find('#');
+            if (fragment_pos != std::string::npos)
+            {
+                query = str.substr(path_size, fragment_pos - path_size);
+                fragment = str.substr(fragment_pos);
+            }
+            else
+            {
+                query = str.substr(path_size);
+            }
+
+            std::string path = str.substr(0, path_size);
+
+            result = escapeUriPath(path) + escapeUriQuery(query) + escapeUriPath(fragment);
+        }
+    }
+
+    if (result.empty())
+    {
+        // Not a known scheme or no data part, try just escaping as Uri path
+        result = escapeUriPath(str);
+    }
+    return result;
+}
+
 LLURI::LLURI()
 {
 }
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 9e44cc7da2ac10fa7b2d1d21c47f0881988bfef2..b8fca0ca5162bd3fec32da9bada17268205a86b3 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -157,6 +157,14 @@ class LL_COMMON_API LLURI
 		const std::string& allowed,
 		bool is_allowed_sorted = false);
 
+	/**
+	 * @brief Break string into data part and path or sheme
+	 * and escape path (if present) and data.
+	 * Data part is not allowed to have path related symbols
+	 * @param str The raw URI to escape.
+	 */
+	static std::string escapePathAndData(const std::string &str);
+
 	/**
 	 * @brief unescape an escaped URI string.
 	 *
diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp
index 4c64f15ca78efa54e93a9353177631185fa2eed1..1a4c6641b9c0f096906e296952b950fa6eb5f171 100644
--- a/indra/llcommon/tests/lluri_test.cpp
+++ b/indra/llcommon/tests/lluri_test.cpp
@@ -383,6 +383,41 @@ namespace tut
 		ensure_equals("query",		u.query(),		"redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
 		ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
 	}
+
+	template<> template<>
+	void URITestObject::test<20>()
+	{
+        set_test_name("escapePathAndData uri test");
+
+        // Basics scheme:[//authority]path[?query][#fragment]
+        ensure_equals(LLURI::escapePathAndData("dirname?query"),
+            "dirname?query");
+        ensure_equals(LLURI::escapePathAndData("dirname?query=data"),
+            "dirname?query=data");
+        ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query#fragment"),
+            "host://dirname/subdir%20name?query#fragment");
+        ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query=some@>data#fragment"),
+            "host://dirname/subdir%20name?query=some@%3Edata#fragment");
+        ensure_equals(LLURI::escapePathAndData("host://dir[name/subdir name?query=some[data#fra[gment"),
+            "host://dir[name/subdir%20name?query=some%5Bdata#fra[gment");
+        ensure_equals(LLURI::escapePathAndData("mailto:zero@ll.com"),
+            "mailto:zero@ll.com");
+        // pre-escaped
+        ensure_equals(LLURI::escapePathAndData("host://dirname/subdir%20name"),
+            "host://dirname/subdir%20name");
+
+        // data:[<mediatype>][;base64],<data>
+        ensure_equals(LLURI::escapePathAndData("data:,Hello, World!"),
+            "data:,Hello%2C%20World%21");
+        ensure_equals(LLURI::escapePathAndData("data:text/html,<h1>Hello, World!</h1>"),
+            "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
+        // pre-escaped
+        ensure_equals(LLURI::escapePathAndData("data:text/html,%3Ch1%3EHello%2C%20World!</h1>"),
+            "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
+        // assume that base64 does not need escaping
+        ensure_equals(LLURI::escapePathAndData("data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="),
+            "data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?=");
+    }
 }
 
 
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index abd304f6a55c5e63f91cbd6f78b9385991c79b7e..975ce8a4d5b338f0cd14377bc0aa84f96efa8026 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -355,7 +355,8 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
 	}
     if (op->mStatus)
     {
-        int http_status(HTTP_OK);
+        // note: CURLINFO_RESPONSE_CODE requires a long - https://curl.haxx.se/libcurl/c/CURLINFO_RESPONSE_CODE.html
+        long http_status(HTTP_OK);
 
         if (handle)
         {
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index 867b2bb47bac2311de1ea1c6a24be455163c9ce2..90b7272efa78f17d4314f8b07a763b23f0ba3b23 100644
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
@@ -181,7 +181,7 @@ bool LLImageBMP::updateData()
 		}
 	}
 	else
-	if( 12 <= header.mSize && 64 <= header.mSize )
+	if( 12 <= header.mSize && header.mSize <= 64 )
 	{
 		setLastError("OS/2 2.x BMP files are not supported");
 		return false;
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 280d2653d35f6694379dc42ff66d00ccf5fe3169..0e2f62f9db85a28a5684abee685e1f0d2be02d67 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -401,7 +401,7 @@ class LLOctreeNode : public LLTreeNode<T>
 				child->insert(data);
 			}
 		}
-		else 
+		else if (parent)
 		{
 			//it's not in here, give it to the root
 			OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@@ -416,6 +416,13 @@ class LLOctreeNode : public LLTreeNode<T>
 
 			node->insert(data);
 		}
+		else
+		{
+			// It's not in here, and we are root.
+			// LLOctreeRoot::insert() should have expanded
+			// root by now, something is wrong
+			OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL;
+		}
 
 		return false;
 	}
@@ -763,10 +770,15 @@ class LLOctreeRoot : public LLOctreeNode<T>
 			{
 				LLOctreeNode<T>::insert(data);
 			}
-			else
+			else if (node->isInside(data->getPositionGroup()))
 			{
 				node->insert(data);
 			}
+			else
+			{
+				// calling node->insert(data) will return us to root
+				OCT_ERRS << "Failed to insert data at child node" << LL_ENDL;
+			}
 		}
 		else if (this->getChildCount() == 0)
 		{
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index b15b98db806b04ae7204cd2a6c4482a5d0f7b13a..7caf0766b72f75f05b2c1c3a2553f6b19549073b 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -265,7 +265,7 @@ LLSocket::~LLSocket()
 void LLSocket::setBlocking(S32 timeout)
 {
 	// set up the socket options
-	ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout));
+	ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO
 	ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0));
 	ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE));
 	ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE));
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index eefac1de21b921df9685ec8f3b0096e294d25716..950599217f83195b1adb0ff4ed07a461030eafb0 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -476,7 +476,8 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
   	rv = apr_socket_send(apr_socket, dataout, &outlen);
 	if (APR_SUCCESS != rv)
 	{
-		LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
+		char buf[MAX_STRING];
+		LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
 		ll_apr_warn_status(rv);
 	}
 	else if (expected_len != outlen)
@@ -486,13 +487,16 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
 		rv = -1;
 	}
 
+	ms_sleep(1);
+
 	if (APR_SUCCESS == rv)
 	{
 		expected_len = maxinlen;
 		rv = apr_socket_recv(apr_socket, datain, &maxinlen);
 		if (rv != APR_SUCCESS)
 		{
-			LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
+			char buf[MAX_STRING];
+			LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
 			ll_apr_warn_status(rv);
 		}
 		else if (expected_len < maxinlen)
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index ab668dc192dfe7dca62c1ad7311e41ebe0d8b555..c41730ebaaacea9d369885fd04380f3821224f93 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) {
 }
 #endif
 
-BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
 {
 	// Don't leak face objects.  This is also needed to deal with
 	// changed font file names.
@@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	}
 	
 	int error;
-
 #ifdef LL_WINDOWS
-	pFileStream = new llifstream(filename, std::ios::binary);
-	if (pFileStream->is_open())
-	{
-		std::streampos beg = pFileStream->tellg();
-		pFileStream->seekg(0, std::ios::end);
-		std::streampos end = pFileStream->tellg();
-		std::size_t file_size = end - beg;
-		pFileStream->seekg(0, std::ios::beg);
-
-		pFtStream = new LLFT_Stream();
-		pFtStream->base = 0;
-		pFtStream->pos = 0;
-		pFtStream->size = file_size;
-		pFtStream->descriptor.pointer = pFileStream;
-		pFtStream->read = ft_read_cb;
-		pFtStream->close = ft_close_cb;
-
-		FT_Open_Args args;
-		args.flags = FT_OPEN_STREAM;
-		args.stream = (FT_StreamRec*)pFtStream;
-
-		error = FT_Open_Face(gFTLibrary,
-							 &args,
-							 0,
-							 &mFTFace);
-	}
-	else
-	{
-		delete pFileStream;
-		pFileStream = NULL;
-		return FALSE;
-	}
+	error = ftOpenFace(filename, face_n);
 #else
 	error = FT_New_Face( gFTLibrary,
 						 filename.c_str(),
@@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	if (error)
 	{
 #ifdef LL_WINDOWS
-		pFileStream->close();
-		delete pFileStream;
-		delete pFtStream;
-		pFileStream = NULL;
-		pFtStream = NULL;
+		clearFontStreams();
 #endif
 		return FALSE;
 	}
@@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 		// Clean up freetype libs.
 		FT_Done_Face(mFTFace);
 #ifdef LL_WINDOWS
-		pFileStream->close();
-		delete pFileStream;
-		delete pFtStream;
-		pFileStream = NULL;
-		pFtStream = NULL;
+		clearFontStreams();
 #endif
 		mFTFace = NULL;
 		return FALSE;
@@ -285,18 +245,88 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
 	{
 		mStyle |= LLFontGL::BOLD;
-		mStyle &= ~LLFontGL::NORMAL;
 	}
 
 	if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
 	{
 		mStyle |= LLFontGL::ITALIC;
-		mStyle &= ~LLFontGL::NORMAL;
 	}
 
 	return TRUE;
 }
 
+S32 LLFontFreetype::getNumFaces(const std::string& filename)
+{
+	if (mFTFace)
+	{
+		FT_Done_Face(mFTFace);
+		mFTFace = NULL;
+	}
+
+	S32 num_faces = 1;
+
+#ifdef LL_WINDOWS
+	int error = ftOpenFace(filename, 0);
+		
+	if (error)
+	{
+		return 0;
+	}
+	else
+	{
+		num_faces = mFTFace->num_faces;
+	}
+	
+	FT_Done_Face(mFTFace);
+	clearFontStreams();
+	mFTFace = NULL;
+#endif
+
+	return num_faces;
+}
+
+#ifdef LL_WINDOWS
+S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
+{
+	S32 error = -1;
+	pFileStream = new llifstream(filename, std::ios::binary);
+	if (pFileStream->is_open())
+	{
+		std::streampos beg = pFileStream->tellg();
+		pFileStream->seekg(0, std::ios::end);
+		std::streampos end = pFileStream->tellg();
+		std::size_t file_size = end - beg;
+		pFileStream->seekg(0, std::ios::beg);
+
+		pFtStream = new LLFT_Stream();
+		pFtStream->base = 0;
+		pFtStream->pos = 0;
+		pFtStream->size = file_size;
+		pFtStream->descriptor.pointer = pFileStream;
+		pFtStream->read = ft_read_cb;
+		pFtStream->close = ft_close_cb;
+
+		FT_Open_Args args;
+		args.flags = FT_OPEN_STREAM;
+		args.stream = (FT_StreamRec*)pFtStream;
+		error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
+	}
+	return error;
+}
+
+void LLFontFreetype::clearFontStreams()
+{
+	if (pFileStream)
+	{
+		pFileStream->close();
+	}
+	delete pFileStream;
+	delete pFtStream;
+	pFileStream = NULL;
+	pFtStream = NULL;
+}
+#endif
+
 void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
 {
 	mFallbackFonts = font;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index aadebf5e70b665c37b61d1e8f82735e15a4c0c45..1afe84e770f6c289708cc6bbff9d007971cf9da1 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -84,7 +84,14 @@ class LLFontFreetype : public LLRefCount, public LLTrace::MemTrackable<LLFontFre
 
 	// is_fallback should be true for fallback fonts that aren't used
 	// to render directly (Unicode backup, primarily)
-	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0);
+
+	S32 getNumFaces(const std::string& filename);
+
+#ifdef LL_WINDOWS
+	S32 ftOpenFace(const std::string& filename, S32 face_n);
+	void clearFontStreams();
+#endif
 
 	typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
 
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 8cd18c5fa1987cd4a1b364a076f901e6221348a3..86a4c35e6dec1ef309c370bdc2b0a40fb7dff272 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -89,14 +89,24 @@ void LLFontGL::destroyGL()
 	mFontFreetype->destroyGL();
 }
 
-BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
 {
 	if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
 	{
 		mFontFreetype = new LLFontFreetype;
 	}
 
-	return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
+	return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n);
+}
+
+S32 LLFontGL::getNumFaces(const std::string& filename)
+{
+	if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
+	{
+		mFontFreetype = new LLFontFreetype;
+	}
+
+	return mFontFreetype->getNumFaces(filename);
 }
 
 static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
@@ -860,10 +870,6 @@ void LLFontGL::destroyAllGL()
 U8 LLFontGL::getStyleFromString(const std::string &style)
 {
 	S32 ret = 0;
-	if (style.find("NORMAL") != style.npos)
-	{
-		ret |= NORMAL;
-	}
 	if (style.find("BOLD") != style.npos)
 	{
 		ret |= BOLD;
@@ -883,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style)
 std::string LLFontGL::getStringFromStyle(U8 style)
 {
 	std::string style_string;
-	if (style & NORMAL)
+	if (style == NORMAL)
 	{
 		style_string += "|NORMAL";
 	}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 7d0e53f60f17830f973bdb5395886e379c288eb6..10891faed9c1318b918b1beb6bb6d2c64f741c8f 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -87,7 +87,9 @@ class LLFontGL
 
 	void destroyGL();
 
-	BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
+	BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0);
+
+	S32 getNumFaces(const std::string& filename);
 
 	S32 render(const LLWString &text, S32 begin_offset, 
 				const LLRect& rect, 
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 3c829596ce5f2a0a50c3fe390dd1d18d10ff4710..dbe71e2882ed177e82f3f1f44368c97c751ac483 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -44,6 +44,8 @@ using std::map;
 bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
 bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
 
+const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
+
 LLFontDescriptor::LLFontDescriptor():
 	mStyle(0)
 {
@@ -60,6 +62,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,
 {
 }
 
+LLFontDescriptor::LLFontDescriptor(const std::string& name,
+	const std::string& size,
+	const U8 style,
+	const string_vec_t& file_names,
+	const string_vec_t& ft_collection_listections) :
+	LLFontDescriptor(name, size, style, file_names)
+{
+	mFontCollectionsList = ft_collection_listections;
+}
+
 LLFontDescriptor::LLFontDescriptor(const std::string& name,
 								   const std::string& size, 
 								   const U8 style):
@@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const
 	if (removeSubString(new_name,"Italic"))
 		new_style |= LLFontGL::ITALIC;
 
-	return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
+	return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());
 }
 
 LLFontRegistry::LLFontRegistry(bool create_gl_textures)
@@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
 			success = success || init_succ;
 		}
 	}
+
 	//if (success)
 	//	dump();
 
@@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
 		{
 			std::string font_file_name = child->getTextContents();
 			desc.getFileNames().push_back(font_file_name);
+			
+			if (child->hasAttribute("load_collection"))
+			{
+				BOOL col = FALSE;
+				child->getAttributeBOOL("load_collection", col);
+				if (col)
+				{
+					desc.getFontCollectionsList().push_back(font_file_name);
+				}
+			}
 		}
 		else if (child->hasName("os"))
 		{
@@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
 					match_file_names.insert(match_file_names.begin(),
 											desc.getFileNames().begin(),
 											desc.getFileNames().end());
+
+					string_vec_t collections_list = match_desc->getFontCollectionsList();
+					collections_list.insert(collections_list.begin(),
+						desc.getFontCollectionsList().begin(),
+						desc.getFontCollectionsList().end());
+
 					LLFontDescriptor new_desc = *match_desc;
 					new_desc.getFileNames() = match_file_names;
+					new_desc.getFontCollectionsList() = collections_list;
 					registry->mFontMap.erase(*match_desc);
 					registry->mFontMap[new_desc] = NULL;
 				}
@@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 	// Build list of font names to look for.
 	// Files specified for this font come first, followed by those from the default descriptor.
 	string_vec_t file_names = match_desc->getFileNames();
+	string_vec_t ft_collection_list = match_desc->getFontCollectionsList();
 	string_vec_t default_file_names;
 	LLFontDescriptor default_desc("default",s_template_string,0);
 	const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
@@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 		file_names.insert(file_names.end(),
 						  match_default_desc->getFileNames().begin(),
 						  match_default_desc->getFileNames().end());
+		ft_collection_list.insert(ft_collection_list.end(),
+			match_default_desc->getFontCollectionsList().begin(),
+			match_default_desc->getFontCollectionsList().end());
 	}
 
 	// Add ultimate fallback list - generated dynamically on linux,
@@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 		file_name_it != file_names.end(); 
 		++file_name_it)
 	{
-		LLFontGL *fontp = new LLFontGL;
-		std::string font_path = local_path + *file_name_it;
+		LLFontGL *fontp = NULL;
+		string_vec_t font_paths;
+		font_paths.push_back(local_path + *file_name_it);
+		font_paths.push_back(sys_path + *file_name_it);
+#if LL_DARWIN
+		font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
+#endif
+		
+		bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
 		// *HACK: Fallback fonts don't render, so we can use that to suppress
 		// creation of OpenGL textures for test apps. JC
 		BOOL is_fallback = !is_first_found || !mCreateGLTextures;
 		F32 extra_scale = (is_fallback)?fallback_scale:1.0;
-		if (!fontp->loadFace(font_path, extra_scale * point_size,
-							 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
+		F32 point_size_scale = extra_scale * point_size;
+		bool is_font_loaded = false;
+		for(string_vec_t::iterator font_paths_it = font_paths.begin();
+			font_paths_it != font_paths.end();
+			++font_paths_it)
 		{
-			font_path = sys_path + *file_name_it;
-
-			if (!fontp->loadFace(font_path, extra_scale * point_size,
-								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
+			fontp = new LLFontGL;
+			S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1;
+			for (S32 i = 0; i < num_faces; i++)
 			{
-				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
-				delete fontp;
-				fontp = NULL;
+				if (fontp == NULL)
+				{
+					fontp = new LLFontGL;
+				}
+				if (fontp->loadFace(*font_paths_it, point_size_scale,
+								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i))
+				{
+					is_font_loaded = true;
+					if (is_first_found)
+					{
+						result = fontp;
+						is_first_found = false;
+					}
+					else
+					{
+						fontlist.push_back(fontp->mFontFreetype);
+						delete fontp;
+						fontp = NULL;
+					}
+				}
+				else
+				{
+					delete fontp;
+					fontp = NULL;
+				}
 			}
+			if (is_font_loaded) break;
 		}
-		
-		if(fontp)
+		if(!is_font_loaded)
 		{
-			if (is_first_found)
-			{
-				result = fontp;
-				is_first_found = false;
-			}
-			else
-			{
-				fontlist.push_back(fontp->mFontFreetype);
-				delete fontp;
-				fontp = NULL;
-			}
+			LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it <<  LL_ENDL;
+			delete fontp;
+			fontp = NULL;
 		}
 	}
 
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 177eb6c8a5db548907bd3f2c94d0fa9808e644ff..e30c81c63018593ed561b6e9b51f40d9c31e9af8 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -40,6 +40,7 @@ class LLFontDescriptor
 	LLFontDescriptor();
 	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
 	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names);
+	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections);
 	LLFontDescriptor normalize() const;
 
 	bool operator<(const LLFontDescriptor& b) const;
@@ -52,6 +53,8 @@ class LLFontDescriptor
 	void setSize(const std::string& size) { mSize = size; }
 	const std::vector<std::string>& getFileNames() const { return mFileNames; }
 	std::vector<std::string>& getFileNames() { return mFileNames; }
+	const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; }
+	std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; }
 	const U8 getStyle() const { return mStyle; }
 	void setStyle(U8 style) { mStyle = style; }
 
@@ -59,6 +62,7 @@ class LLFontDescriptor
 	std::string mName;
 	std::string mSize;
 	string_vec_t mFileNames;
+	string_vec_t mFontCollectionsList;
 	U8 mStyle;
 };
 
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 41c7d67f24a6e215863484b516bba715becd40d2..0afd32f33279bde6fbbe67ea9d2e21e39951eaec 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -122,6 +122,7 @@ void LLTextBox::setEnabled(BOOL enabled)
 		LLTextBase::setReadOnly(read_only);
 		updateSegments();
 	}
+	LLTextBase::setEnabled(enabled);
 }
 
 void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params )
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 220cee4c90b37eb8e100f31d169bb4d250a1e034..b1534bb5e4a7daa13c3c983f202b4a8cfb166b50 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -44,7 +44,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
 	bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
 	if (!success)
 	{
-		LL_ERRS() << "Couldn't load string table " << xml_filename << LL_ENDL;
+		LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from  https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
 		return false;
 	}
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 10bd3cbb9127929bfb630a5e095f667d98835064..99af16110289c47d38327994d0a095fc91b0e80f 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -110,9 +110,9 @@ void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
 unsigned long getVramSize(GLViewRef view);
 float getDeviceUnitSize(GLViewRef view);
-const CGPoint getContentViewBoundsPosition(NSWindowRef window);
-const CGSize getContentViewBoundsSize(NSWindowRef window);
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
+CGPoint getContentViewBoundsPosition(NSWindowRef window);
+CGSize getContentViewBoundsSize(NSWindowRef window);
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
 void getCursorPos(NSWindowRef window, float* pos);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 8fece7c5c7cc6c61e324b9ead36d8007c8166ee2..f895c1764396b862aa4adf246c3f22e9b7816559 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -258,17 +258,17 @@ float getDeviceUnitSize(GLViewRef view)
 	return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
 }
 
-const CGPoint getContentViewBoundsPosition(NSWindowRef window)
+CGPoint getContentViewBoundsPosition(NSWindowRef window)
 {
 	return [[(LLNSWindow*)window contentView] bounds].origin;
 }
 
-const CGSize getContentViewBoundsSize(NSWindowRef window)
+CGSize getContentViewBoundsSize(NSWindowRef window)
 {
 	return [[(LLNSWindow*)window contentView] bounds].size;
 }
 
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
 {
     return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
 }
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 6dec131a3478146ae0823dedf43a559f99fa7239..3554f90be8c558f600888849b26c2f616cfa1321 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -382,7 +382,10 @@ void callWindowFocus()
 
 void callWindowUnfocus()
 {
-	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+	if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+	{
+		gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+	}
 }
 
 void callWindowHide()
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 985bd79d133bb172c64313603078e8a5e5866ddb..e05f5075067a406c941094a337fb8805a12b3d86 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -741,6 +741,17 @@ void LLWindowWin32::restore()
 	SetFocus(mWindowHandle);
 }
 
+bool destroy_window_handler(HWND &hWnd)
+{
+    __try
+    {
+        return DestroyWindow(hWnd);
+    }
+    __except (EXCEPTION_EXECUTE_HANDLER)
+    {
+        return false;
+    }
+}
 
 // close() destroys all OS-specific code associated with a window.
 // Usually called from LLWindowManager::destroyWindow()
@@ -814,7 +825,7 @@ void LLWindowWin32::close()
 	ShowWindow(mWindowHandle, SW_HIDE);
 
 	// This causes WM_DESTROY to be sent *immediately*
-	if (!DestroyWindow(mWindowHandle))
+	if (!destroy_window_handler(mWindowHandle))
 	{
 		OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
 			mCallbacks->translateString("MBShutdownErr"),
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 2a8eb20af9db50dcaf64ca5c8270ec9211f2ddcb..eead92fd8e8f6e555d3e123fe5b97e300f2506b6 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -531,7 +531,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 
 				// now we can set page zoom factor
-				mCEFLib->setPageZoom(message_in.getValueReal("factor"));
+				F32 factor = (F32)message_in.getValueReal("factor");
+#if LL_DARWIN
+				//temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+				factor*=1.001;
+#endif
+				mCEFLib->setPageZoom(factor);
 
 				// Plugin gets to decide the texture parameters to use.
 				mDepth = 4;
@@ -736,6 +741,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			if (message_name == "set_page_zoom_factor")
 			{
 				F32 factor = (F32)message_in.getValueReal("factor");
+#if LL_DARWIN
+				//temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+				factor*=1.001;
+#endif
 				mCEFLib->setPageZoom(factor);
 			}
 			if (message_name == "browse_stop")
@@ -813,7 +822,8 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
 	// adding new code below in unicodeInput means we don't send ascii chars
 	// here too or we get double key presses on a mac.
 	bool esc_key = (event_umodchars == 27);
-	if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f ))
+	bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP);
+	if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up)
 	{
 		mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers, 
 										event_keycode, event_chars, 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c18b2c9a959e5964bd6a9006b7355f82a8bc5cb8..2b35d18329eb536a3f2361341a869a156bd609dd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -201,7 +201,6 @@ set(viewer_SOURCE_FILES
     llexperiencelog.cpp
     llexternaleditor.cpp
     llface.cpp
-    llfacebookconnect.cpp
     llfasttimerview.cpp
     llfavoritesbar.cpp
     llfeaturemanager.cpp
@@ -245,7 +244,6 @@ set(viewer_SOURCE_FILES
     llfloaterexperiencepicker.cpp
     llfloaterexperienceprofile.cpp
     llfloaterexperiences.cpp
-    llfloaterfacebook.cpp
     llfloaterflickr.cpp
     llfloaterfonttest.cpp
     llfloatergesture.cpp
@@ -828,7 +826,6 @@ set(viewer_HEADER_FILES
     llexperiencelog.h
     llexternaleditor.h
     llface.h
-    llfacebookconnect.h
     llfasttimerview.h
     llfavoritesbar.h
     llfeaturemanager.h
@@ -872,7 +869,6 @@ set(viewer_HEADER_FILES
     llfloaterexperiencepicker.h
     llfloaterexperienceprofile.h
     llfloaterexperiences.h
-    llfloaterfacebook.h
     llfloaterflickr.h
     llfloaterfonttest.h
     llfloatergesture.h
@@ -1885,12 +1881,12 @@ if (WINDOWS)
 
     # sets the 'working directory' for debugging from visual studio.
     # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
-    if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
+    if (NOT UNATTENDED)
         set_property(
           TARGET ${VIEWER_BINARY_NAME}
           PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
           )
-    endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
+    endif (NOT UNATTENDED)
 
     if (PACKAGE)
       add_custom_command(
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index dc0208aba8e455dd24c8e48bf83f94c6bffc43d8..91e4a9f2622445cdde5b075e2f7d95e245821b59 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.3.1
+6.3.2
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 412d3a53b327fc5dccb9951a033606039a6e1023..cab0c523b2300fd335e77843f59c1259bfea8e98 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -228,16 +228,6 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="snapshot"
            />
-  <command name="facebook"
-           available_in_toybox="true"
-           icon="Command_Facebook_Icon"
-           label_ref="Command_Facebook_Label"
-           tooltip_ref="Command_Facebook_Tooltip"
-           execute_function="Floater.ToggleOrBringToFront"
-           execute_parameters="facebook"
-           is_running_function="Floater.IsOpen"
-           is_running_parameters="facebook"
-           />
   <command name="flickr"
            available_in_toybox="true"
            icon="Command_Flickr_Icon"
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 3d4bd659f19f4eaee9dbc319387c38cc03d39fac..8f4ca6c6337e47bde432c347c251079a8d657a97 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -414,5 +414,16 @@
         <key>Value</key>
         <string>Snapshot</string>
       </map>
+      <key>ExperienceSearchMaturity</key>
+      <map>
+        <key>Comment</key>
+        <string>Setting for the user's preferred Max Content rating for Experiences search (Default rating is General)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>U32</string>
+        <key>Value</key>
+        <integer>2</integer>
+      </map>
     </map>
 </llsd>
diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml
index 36e4eb91fdc1a67d7cb4417dd2b87e58b9f7fa91..eec0d81e8b001a7e5ed3aaa4127b43d00866fa24 100644
--- a/indra/newview/app_settings/toolbars.xml
+++ b/indra/newview/app_settings/toolbars.xml
@@ -21,7 +21,6 @@
     <command name="voice"/>
     <command name="minimap"/>
     <command name="snapshot"/>
-    <command name="facebook"/>
   </left_toolbar>
   <right_toolbar
     button_display_mode="icons_only">
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index d1d5301efec46cc101d758736e7892e6b206be6c..8838b6d0be117e982dd66700d65cc47b2157e234 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -346,6 +346,11 @@ Call CheckWillUninstallV2		# Check if Second Life is already installed
 StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
 PRESERVE_DONE:
 
+# Viewer had "SLLauncher" for some time and we was seting "IsHostApp" for viewer, make sure to clean it up
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
+ClearErrors
+
 Call RemoveProgFilesOnInst		# Remove existing files to prevent certain errors when running the new version of the viewer
 
 # This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
@@ -417,7 +422,7 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
 # URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
 WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
 
-WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
+WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
 ##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
 
 # Write out uninstaller
@@ -464,7 +469,7 @@ DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}"
 DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
 # BUG-2707 Remove entry that disabled SEHOP
 DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
-##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
+DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
 DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
 
 # Clean up shortcuts
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 8bb20476b3e0122d94945b092522d9dd1fbb9f2c..eebcf027a820c5980e8bce847470621d2b5f1ac8 100755
Binary files a/indra/newview/installers/windows/lang_de.nsi and b/indra/newview/installers/windows/lang_de.nsi differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9f0c923253304578408b6b3dd4d0112d78bf3d3d..8b2d591da56abef0782938e5e6924bb577e3dcef 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -743,7 +743,7 @@ BOOL LLAgent::getFlying() const
 //-----------------------------------------------------------------------------
 // setFlying()
 //-----------------------------------------------------------------------------
-void LLAgent::setFlying(BOOL fly)
+void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
 {
 	if (isAgentAvatarValid())
 	{
@@ -772,7 +772,10 @@ void LLAgent::setFlying(BOOL fly)
 			// parcel doesn't let you start fly
 			// gods can always fly
 			// and it's OK if you're already flying
-			make_ui_sound("UISndBadKeystroke");
+			if (fail_sound)
+			{
+				make_ui_sound("UISndBadKeystroke");
+			}
 			return;
 		}
 		if( !was_flying )
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index b1b39b637e48587fd7eda112b16cf7cb1404d16f..ea6f68c482d82472d57d7c5d71082c00365a525d 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -337,7 +337,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	//--------------------------------------------------------------------
 public:
 	BOOL			getFlying() const;
-	void			setFlying(BOOL fly);
+	void			setFlying(BOOL fly, BOOL fail_sound = FALSE);
 	static void		toggleFlying();
 	static bool		enableFlying();
 	BOOL			canFly(); 			// Does this parcel allow you to fly?
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f414ec0d09b8d14ae7599e76be7e1922da5d8aae..90c7791c198da6173c4ca0495f881475e74784ad 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2419,9 +2419,9 @@ bool LLAppViewer::initConfiguration()
 	bool set_defaults = true;
 	if(!loadSettingsFromDirectory("Default", set_defaults))
 	{
-		std::ostringstream msg;
-		msg << "Unable to load default settings file. The installation may be corrupted.";
-		OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+		OSMessageBox(
+			"Unable to load default settings file. The installation may be corrupted.",
+			LLStringUtil::null,OSMB_OK);
 		return false;
 	}
 
@@ -2542,7 +2542,7 @@ bool LLAppViewer::initConfiguration()
 	if(gSavedSettings.getBOOL("DisableCrashLogger"))
 	{
 		LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
-		LLAppViewer::instance()->disableCrashlogger();
+		disableCrashlogger();
 	}
 
 	// Handle initialization from settings.
@@ -2559,7 +2559,7 @@ bool LLAppViewer::initConfiguration()
 		LL_INFOS()	<< msg.str() << LL_ENDL;
 
 		OSMessageBox(
-			msg.str().c_str(),
+			msg.str(),
 			LLStringUtil::null,
 			OSMB_OK);
 
@@ -2669,7 +2669,34 @@ bool LLAppViewer::initConfiguration()
 		ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
 	}
 
+	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+	{
+		// Examining "Language" may not suffice -- see LLUI::getLanguage()
+		// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+		// good because we haven't yet called LLUI::initClass().
+		gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+								 gSavedSettings.getString("Language"));
+	}
+
+	if (gSavedSettings.getBOOL("SpellCheck"))
+	{
+		std::list<std::string> dict_list;
+		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+		if (!dict_list.empty())
+		{
+			LLSpellChecker::setUseSpellCheck(dict_list.front());
+			dict_list.pop_front();
+			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+		}
+	}
+
 	// Handle slurl use. NOTE: Don't let SL-55321 reappear.
+	// This initial-SLURL logic, up through the call to
+	// sendURLToOtherInstance(), must precede LLSplashScreen::show() --
+	// because if sendURLToOtherInstance() succeeds, we take a fast exit,
+	// SKIPPING the splash screen and everything else.
 
     // *FIX: This init code should be made more robust to prevent
     // the issue SL-55321 from returning. One thought is to allow
@@ -2714,6 +2741,27 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
+	// NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
+	std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
+	if ( !nextLoginLocation.empty() )
+	{
+		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
+		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
+	}
+	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
+			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
+	{
+		// If automatic login from command line with --login switch
+		// init StartSLURL location.
+		std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
+		LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
+		LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
+	}
+	else
+	{
+		// the login location will be set by the login panel (see LLPanelLogin)
+	}
+
 	//RN: if we received a URL, hand it off to the existing instance.
 	// don't call anotherInstanceRunning() when doing URL handoff, as
 	// it relies on checking a marker file which will not work when running
@@ -2729,30 +2777,6 @@ bool LLAppViewer::initConfiguration()
 		}
     }
 
-	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
-	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
-	{
-		// Examining "Language" may not suffice -- see LLUI::getLanguage()
-		// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
-		// good because we haven't yet called LLUI::initClass().
-		gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
-								 gSavedSettings.getString("Language"));
-	}
-
-	if (gSavedSettings.getBOOL("SpellCheck"))
-	{
-		std::list<std::string> dict_list;
-		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
-		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
-		if (!dict_list.empty())
-		{
-			LLSpellChecker::setUseSpellCheck(dict_list.front());
-			dict_list.pop_front();
-			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
-		}
-	}
-
-
 	// Display splash screen.  Must be after above check for previous
 	// crash as this dialog is always frontmost.
 	std::string splash_msg;
@@ -2784,30 +2808,15 @@ bool LLAppViewer::initConfiguration()
 	}
 	LLStringUtil::truncate(gWindowTitle, 255);
 
-	//RN: if we received a URL, hand it off to the existing instance.
-	// don't call anotherInstanceRunning() when doing URL handoff, as
-	// it relies on checking a marker file which will not work when running
-	// out of different directories
-
-	if (LLStartUp::getStartSLURL().isValid() &&
-		(gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
-	{
-		if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
-		{
-			// successfully handed off URL to existing instance, exit
-			return false;
-		}
-	}
-
 	//
 	// Check for another instance of the app running
+	// This happens AFTER LLSplashScreen::show(). That may or may not be
+	// important.
 	//
 	if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
 	{
-		std::ostringstream msg;
-		msg << LLTrans::getString("MBAlreadyRunning");
 		OSMessageBox(
-			msg.str(),
+			LLTrans::getString("MBAlreadyRunning"),
 			LLStringUtil::null,
 			OSMB_OK);
 		return false;
@@ -2825,27 +2834,6 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
-   	// NextLoginLocation is set from the command line option
-	std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
-	if ( !nextLoginLocation.empty() )
-	{
-		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
-		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
-	}
-	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
-			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
-	{
-		// If automatic login from command line with --login switch
-		// init StartSLURL location.
-		std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
-		LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
-		LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
-	}
-	else
-	{
-		// the login location will be set by the login panel (see LLPanelLogin)
-	}
-
 	gLastRunVersion = gSavedSettings.getString("LastRunVersion");
 
 	loadColorSettings();
@@ -2869,7 +2857,14 @@ bool LLAppViewer::initConfiguration()
 // keeps growing, necessitating a method all its own.
 void LLAppViewer::initStrings()
 {
-	LLTransUtil::parseStrings("strings.xml", default_trans_args);
+	std::string strings_file = "strings.xml";
+	std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
+	if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
+	{
+		// initial check to make sure files are there failed
+		LL_ERRS() << "Viewer failed to find localization and UI files. Please reinstall viewer from  https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+	}
+	LLTransUtil::parseStrings(strings_file, default_trans_args);
 	LLTransUtil::parseLanguageStrings("language_settings.xml");
 
 	// parseStrings() sets up the LLTrans substitution table. Add this one item.
@@ -3154,6 +3149,10 @@ LLSD LLAppViewer::getViewerInfo() const
     substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0);
     info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution);
 
+#if LL_DARWIN
+    info["HIDPI"] = gHiDPISupport;
+#endif
+
 	// Libraries
 
 	info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
@@ -3296,6 +3295,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const
 	}
 	support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
 	support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
+#if LL_DARWIN
+	support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string);
+#endif
 	support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
 	if (info.has("COMPILER"))
 	{
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 90a5483dc98f2686d779b4851ed51d5945681f53..fe14bc081f2f6cbcf4473c4b75ac276b583018ae 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -374,12 +374,40 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
 
 bool LLCommandLineParser::parseCommandLineString(const std::string& str)
 {
+    std::string cmd_line_string("");
+    if (!str.empty())
+    {
+        bool add_last_c = true;
+        S32 last_c_pos = str.size() - 1; //don't get out of bounds on pos+1, last char will be processed separately
+        for (S32 pos = 0; pos < last_c_pos; ++pos)
+        {
+            cmd_line_string.append(&str[pos], 1);
+            if (str[pos] == '\\')
+            {
+                cmd_line_string.append("\\", 1);
+                if (str[pos + 1] == '\\')
+                {
+                    ++pos;
+                    add_last_c = (pos != last_c_pos);
+                }
+            }
+        }
+        if (add_last_c)
+        {
+            cmd_line_string.append(&str[last_c_pos], 1);
+            if (str[last_c_pos] == '\\')
+            {
+                cmd_line_string.append("\\", 1);
+            }
+        }
+    }
+
     // Split the string content into tokens
-	const char* escape_chars = "\\";
-	const char* separator_chars = "\r\n ";
-	const char* quote_chars = "\"'";
+    const char* escape_chars = "\\";
+    const char* separator_chars = "\r\n ";
+    const char* quote_chars = "\"'";
     boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
-    boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep);
+    boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
     std::vector<std::string> tokens;
     // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
     for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 0f02c23cb04398edda49568374f0bca0d8acfcca..d24dac385f245a570aa937af8558c3c0d890f175 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -566,27 +566,49 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
 									  LLVector4a* normal,
 									  LLVector4a* tangent)
 {
-	LLViewerObject* hit = NULL;
+    if (!mRootVolp)
+    {
+        return NULL;
+    }
 
-	if (lineSegmentBoundingBox(start, end))
-	{
-		LLVector4a local_end = end;
-		LLVector4a local_intersection;
+    LLViewerObject* hit = NULL;
 
-        if (mRootVolp &&
-            mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+    if (lineSegmentBoundingBox(start, end))
+    {
+        LLVector4a local_end = end;
+        LLVector4a local_intersection;
+        if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
         {
             local_end = local_intersection;
             if (intersection)
             {
                 *intersection = local_intersection;
             }
-			
             hit = mRootVolp;
         }
-	}
-		
-	return hit;
+        else
+        {
+            std::vector<LLVOVolume*> volumes;
+            getAnimatedVolumes(volumes);
+
+            for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
+            {
+                LLVOVolume *volp = *vol_it;
+                if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+                {
+                    local_end = local_intersection;
+                    if (intersection)
+                    {
+                        *intersection = local_intersection;
+                    }
+                    hit = volp;
+                    break;
+                }
+            }
+        }
+    }
+
+    return hit;
 }
 
 // virtual
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
deleted file mode 100644
index 43b01fa2f14917ad7ae9970f12434d87b949bab5..0000000000000000000000000000000000000000
--- a/indra/newview/llfacebookconnect.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/** 
- * @file llfacebookconnect.h
- * @author Merov, Cho, Gil
- * @brief Connection to Facebook Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfacebookconnect.h"
-#include "llflickrconnect.h"
-#include "lltwitterconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h"			// for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent"));
-
-// Local functions
-void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
-    // Note: 302 (redirect) is *not* an error that warrants logging
-    if (status != 302)
-    {
-		LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
-    }
-}
-
-void toast_user_for_facebook_success()
-{
-	LLSD args;
-    args["MESSAGE"] = LLTrans::getString("facebook_post_success");
-    LLNotificationsUtil::add("FacebookConnect", args);
-}
-
-LLCore::HttpHeaders::ptr_t get_headers()
-{
-    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
-    // The DebugSlshareLogTag mechanism is intended to trigger slshare-service
-    // debug logging. slshare-service is coded to respond to an X-debug-tag
-    // header by engaging debug logging for that request only. This way a
-    // developer need not muck with the slshare-service image to engage debug
-    // logging. Moreover, the value of X-debug-tag is embedded in each such
-    // log line so the developer can quickly find the log lines pertinent to
-    // THIS session.
-    std::string logtag(gSavedSettings.getString("DebugSlshareLogTag"));
-    if (! logtag.empty())
-    {
-        httpHeaders->append("X-debug-tag", logtag);
-    }
-    return httpHeaders;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-class LLFacebookConnectHandler : public LLCommandHandler
-{
-public:
-	LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
-    
-	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
-	{
-		if (tokens.size() >= 1)
-		{
-			if (tokens[0].asString() == "connect")
-			{
-				if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
-				{
-					// this command probably came from the flickr_web browser, so close it
-					LLFloaterReg::hideInstance("flickr_web");
-
-					// connect to flickr
-					if (query_map.has("oauth_token"))
-					{
-						LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
-					}
-					return true;
-				}
-				else if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
-				{
-					// this command probably came from the twitter_web browser, so close it
-					LLFloaterReg::hideInstance("twitter_web");
-
-					// connect to twitter
-					if (query_map.has("oauth_token"))
-					{
-						LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
-					}
-					return true;
-				}
-				else //if (tokens.size() >= 2 && tokens[1].asString() == "facebook")
-				{
-					// this command probably came from the fbc_web browser, so close it
-					LLFloaterReg::hideInstance("fbc_web");
-
-					// connect to facebook
-					if (query_map.has("code"))
-					{
-						LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
-					}
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-};
-LLFacebookConnectHandler gFacebookConnectHandler;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    LLSD putData;
-    if (!authCode.empty())
-    {
-        putData["code"] = authCode;
-    }
-    if (!authState.empty())
-    {
-        putData["state"] = authState;
-    }
-
-    httpOpts->setWantHeaders(true);
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->putAndSuspend(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers());
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-    if (!status)
-    {
-        if (status == LLCore::HttpStatus(HTTP_FOUND))
-        {
-            std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
-            if (location.empty())
-            {
-                LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
-            }
-            else
-            {
-                openFacebookWeb(location);
-            }
-        }
-    }
-    else
-    {
-        LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_CONNECTED);
-    }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLFacebookConnect::testShareStatus(LLSD &result)
-{
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (status)
-        return true;
-
-    if (status == LLCore::HttpStatus(HTTP_FOUND))
-    {
-        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
-        if (location.empty())
-        {
-            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
-        }
-        else
-        {
-            openFacebookWeb(location);
-        }
-    }
-    if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
-    {
-        LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
-        connectToFacebook();
-    }
-    else
-    {
-        LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_POST_FAILED);
-        log_facebook_connect_error("Share", status.getStatus(), status.toString(),
-            result.get("error_code"), result.get("error_description"));
-    }
-    return false;
-}
-
-void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    httpOpts->setWantHeaders(true);
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers());
-
-    if (testShareStatus(result))
-    {
-        toast_user_for_facebook_success();
-        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_POSTED);
-    }
-}
-
-void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpHeaders::ptr_t httpHeaders(get_headers());
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    httpOpts->setWantHeaders(true);
-    httpOpts->setFollowRedirects(false);
-
-    std::string imageFormat;
-    if (dynamic_cast<LLImagePNG*>(image.get()))
-    {
-        imageFormat = "png";
-    }
-    else if (dynamic_cast<LLImageJPEG*>(image.get()))
-    {
-        imageFormat = "jpg";
-    }
-    else
-    {
-        LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
-        return;
-    }
-
-    // All this code is mostly copied from LLWebProfile::post()
-    static const std::string boundary = "----------------------------0123abcdefab";
-
-    std::string contentType = "multipart/form-data; boundary=" + boundary;
-    httpHeaders->append("Content-Type", contentType.c_str());
-
-    LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); // 
-    LLCore::BufferArrayStream body(raw.get());
-
-    // *NOTE: The order seems to matter.
-    body << "--" << boundary << "\r\n"
-        << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
-        << caption << "\r\n";
-
-    body << "--" << boundary << "\r\n"
-        << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
-        << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
-    // Insert the image data.
-    // *FIX: Treating this as a string will probably screw it up ...
-    U8* image_data = image->getData();
-    for (S32 i = 0; i < image->getDataSize(); ++i)
-    {
-        body << image_data[i];
-    }
-
-    body << "\r\n--" << boundary << "--\r\n";
-
-    setConnectionState(LLFacebookConnect::FB_POSTING);
-
-    LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders);
-
-    if (testShareStatus(result))
-    {
-        toast_user_for_facebook_success();
-        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_POSTED);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookDisconnectCoro()
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers());
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-    if (!status && (status != LLCore::HttpStatus(HTTP_FOUND)))
-    {
-        LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
-        log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(),
-            result.get("error_code"), result.get("error_description"));
-    }
-    else
-    {
-        LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL;
-        clearInfo();
-        clearContent();
-        //Notify state change
-        setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
-    }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
-
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers());
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (!status)
-    {
-        if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) )
-        {
-            LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
-            if (autoConnect)
-            {
-                connectToFacebook();
-            }
-            else
-            {
-                setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
-            }
-        }
-        else
-        {
-            LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
-            setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
-            log_facebook_connect_error("Connected", status.getStatus(), status.toString(),
-                result.get("error_code"), result.get("error_description"));
-        }
-    }
-    else
-    {
-        LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL;
-        setConnectionState(LLFacebookConnect::FB_CONNECTED);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectInfoCoro()
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    httpOpts->setWantHeaders(true);
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers());
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (status == LLCore::HttpStatus(HTTP_FOUND))
-    {
-        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
-        if (location.empty())
-        {
-            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
-        }
-        else
-        {
-            openFacebookWeb(location);
-        }
-    }
-    else if (!status)
-    {
-        LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL;
-        log_facebook_connect_error("Info", status.getStatus(), status.toString(),
-            result.get("error_code"), result.get("error_description"));
-    }
-    else
-    {
-        LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
-        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
-        storeInfo(result);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectFriendsCoro()
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
-    httpOpts->setFollowRedirects(false);
-
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers());
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (status == LLCore::HttpStatus(HTTP_FOUND))
-    {
-        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
-        if (location.empty())
-        {
-            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
-        }
-        else
-        {
-            openFacebookWeb(location);
-        }
-    }
-    else if (!status)
-    {
-        LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL;
-        log_facebook_connect_error("Info", status.getStatus(), status.toString(),
-            result.get("error_code"), result.get("error_description"));
-    }
-    else
-    {
-        LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL;
-        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
-        LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
-        storeContent(content);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLFacebookConnect::LLFacebookConnect()
-:	mConnectionState(FB_NOT_CONNECTED),
-	mConnected(false),
-	mInfo(),
-    mContent(),
-	mRefreshInfo(false),
-	mRefreshContent(false),
-	mReadFromMaster(false)
-{
-}
-
-void LLFacebookConnect::openFacebookWeb(std::string url)
-{
-	LLFloaterWebContent::Params p;
-    p.url(url);
-    p.show_chrome(true);
-    p.allow_back_forward_navigation(false);
-    p.clean_browser(true);
-	LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
-	//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
-	//So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event 
-	//occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
-	//fbc_web floater contains the "webbrowser" panel.    JIRA: ACME-744
-	gFocusMgr.setKeyboardFocus( floater );
-
-	//LLUrlAction::openURLExternal(url);
-}
-
-std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master)
-{
-    std::string url("");
-    LLViewerRegion *regionp = gAgent.getRegion();
-    if (regionp)
-    {
-		//url = "http://pdp15.lindenlab.com/fbc/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
-		url = regionp->getCapability("FacebookConnect");
-        url += route;
-    
-        if (include_read_from_master && mReadFromMaster)
-        {
-            url += "?read_from_master=true";
-        }
-    }
-	return url;
-}
-
-void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
-{
-    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
-
-    LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro",
-        boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state));
-}
-
-void LLFacebookConnect::disconnectFromFacebook()
-{
-    LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro",
-        boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this));
-}
-
-void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
-{
-    setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
-
-    LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro",
-        boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect));
-}
-
-void LLFacebookConnect::loadFacebookInfo()
-{
-	if(mRefreshInfo)
-	{
-        LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro",
-            boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this));
-	}
-}
-
-void LLFacebookConnect::loadFacebookFriends()
-{
-	if(mRefreshContent)
-	{
-        LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro",
-            boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this));
-	}
-}
-
-void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, 
-    const std::string& description, const std::string& image, const std::string& message)
-{
-    setConnectionState(LLFacebookConnect::FB_POSTING);
-
-	LLSD body;
-	if (!location.empty())
-    {
-		body["location"] = location;
-    }
-	if (!name.empty())
-    {
-		body["name"] = name;
-    }
-	if (!description.empty())
-    {
-		body["description"] = description;
-    }
-	if (!image.empty())
-    {
-		body["image"] = image;
-    }
-	if (!message.empty())
-    {
-		body["message"] = message;
-    }
-
-    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
-        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body));
-}
-
-void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
-{
-    setConnectionState(LLFacebookConnect::FB_POSTING);
-
-	LLSD body;
-	body["image"] = image_url;
-	body["caption"] = caption;
-	
-    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
-        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body));
-}
-
-void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
-{
-    setConnectionState(LLFacebookConnect::FB_POSTING);
-
-    LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro",
-        boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption));
-}
-
-void LLFacebookConnect::updateStatus(const std::string& message)
-{
-	LLSD body;
-	body["message"] = message;
-
-    setConnectionState(LLFacebookConnect::FB_POSTING);
-
-    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
-        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body));
-}
-
-void LLFacebookConnect::storeInfo(const LLSD& info)
-{
-	mInfo = info;
-	mRefreshInfo = false;
-
-	sInfoWatcher->post(info);
-}
-
-const LLSD& LLFacebookConnect::getInfo() const
-{
-	return mInfo;
-}
-
-void LLFacebookConnect::clearInfo()
-{
-	mInfo = LLSD();
-}
-
-void LLFacebookConnect::storeContent(const LLSD& content)
-{
-    mContent = content;
-	mRefreshContent = false;
-
-	sContentWatcher->post(content);
-}
-
-const LLSD& LLFacebookConnect::getContent() const
-{
-    return mContent;
-}
-
-void LLFacebookConnect::clearContent()
-{
-    mContent = LLSD();
-}
-
-void LLFacebookConnect::setDataDirty()
-{
-	mRefreshInfo = true;
-	mRefreshContent = true;
-}
-
-void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state)
-{
-	if(connection_state == FB_CONNECTED)
-	{
-		mReadFromMaster = true;
-		setConnected(true);
-		setDataDirty();
-	}
-	else if(connection_state == FB_NOT_CONNECTED)
-	{
-		setConnected(false);
-	}
-	else if(connection_state == FB_POSTED)
-	{
-		mReadFromMaster = false;
-	}
-
-	if (mConnectionState != connection_state)
-	{
-		// set the connection state before notifying watchers
-		mConnectionState = connection_state;
-
-		LLSD state_info;
-		state_info["enum"] = connection_state;
-		sStateWatcher->post(state_info);
-	}
-}
-
-void LLFacebookConnect::setConnected(bool connected)
-{
-	mConnected = connected;
-}
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
deleted file mode 100644
index 7fd4070f54dfeb872b98ffc0b2e322fe3d9e44f7..0000000000000000000000000000000000000000
--- a/indra/newview/llfacebookconnect.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/** 
- * @file llfacebookconnect.h
- * @author Merov, Cho, Gil
- * @brief Connection to Facebook Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFACEBOOKCONNECT_H
-#define LL_LLFACEBOOKCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLFacebookConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to get Facebook OpenGraph data.
- */
-class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
-{
-	LLSINGLETON(LLFacebookConnect);
-	~LLFacebookConnect() {};
-	LOG_CLASS(LLFacebookConnect);
-public:
-    enum EConnectionState
-	{
-		FB_NOT_CONNECTED = 0,
-		FB_CONNECTION_IN_PROGRESS = 1,
-		FB_CONNECTED = 2,
-		FB_CONNECTION_FAILED = 3,
-		FB_POSTING = 4,
-		FB_POSTED = 5,
-		FB_POST_FAILED = 6,
-		FB_DISCONNECTING = 7,
-		FB_DISCONNECT_FAILED = 8
-	};
-	
-	void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = "");	// Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use.
-	void disconnectFromFacebook();																	// Disconnect from the FBC service.
-    void checkConnectionToFacebook(bool auto_connect = false);										// Check if an access token is available on the FBC service. If not, call connectToFacebook().
-    
-	void loadFacebookInfo();
-    void loadFacebookFriends();
-	void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
-    void sharePhoto(const std::string& image_url, const std::string& caption);
-	void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
-	void updateStatus(const std::string& message);
-	
-	void storeInfo(const LLSD& info);
-	const LLSD& getInfo() const;
-	void clearInfo();
-	void storeContent(const LLSD& content);
-    const LLSD& getContent() const;
-	void clearContent();
-	void setDataDirty();
-    
-    void setConnectionState(EConnectionState connection_state);
-	void setConnected(bool connected);
-	bool isConnected() { return mConnected; }
-	bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); }
-    EConnectionState getConnectionState() { return mConnectionState; }
-    
-    void openFacebookWeb(std::string url);
-
-private:
-
- 	std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
-    EConnectionState mConnectionState;
-	BOOL mConnected;
-	LLSD mInfo;
-    LLSD mContent;
-	bool mRefreshInfo;
-	bool mRefreshContent;
-	bool mReadFromMaster;
-	
-	static boost::scoped_ptr<LLEventPump> sStateWatcher;
-	static boost::scoped_ptr<LLEventPump> sInfoWatcher;
-	static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
-    bool testShareStatus(LLSD &results);
-    void facebookConnectCoro(std::string authCode, std::string authState);
-    void facebookConnectedCheckCoro(bool autoConnect);
-    void facebookDisconnectCoro();
-    void facebookShareCoro(std::string route, LLSD share);
-    void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption);
-    void facebookConnectInfoCoro();
-    void facebookConnectFriendsCoro();
-};
-
-#endif // LL_LLFACEBOOKCONNECT_H
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index f68e63cb96365185725fe1c8feb47197667b3df5..d90f03b403ccb36dd4d3d4f7c8cef26a42402d92 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -43,6 +43,7 @@
 #include "llsdserialize.h"
 #include "lltooltip.h"
 #include "llbutton.h"
+#include "llscrollbar.h"
 
 #include "llappviewer.h"
 #include "llviewertexturelist.h"
@@ -128,7 +129,8 @@ void LLFastTimerView::setPauseState(bool pause_state)
 BOOL LLFastTimerView::postBuild()
 {
 	LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
-	
+	mScrollBar = getChild<LLScrollbar>("scroll_vert");
+
 	pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
 	return TRUE;
 }
@@ -183,7 +185,7 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
 
 BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (x < mBarRect.mLeft) 
+	if (x < mScrollBar->getRect().mLeft)
 	{
 		BlockTimerStatHandle* idp = getLegendID(y);
 		if (idp)
@@ -284,7 +286,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 			}
 		}
 	}
-	else if (x < mBarRect.mLeft) 
+	else if (x < mScrollBar->getRect().mLeft) 
 	{
 		BlockTimerStatHandle* timer_id = getLegendID(y);
 		if (timer_id)
@@ -335,7 +337,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
 	else
 	{
 		// tooltips for timer legend
-		if (x < mBarRect.mLeft) 
+		if (x < mScrollBar->getRect().mLeft) 
 		{
 			BlockTimerStatHandle* idp = getLegendID(y);
 			if (idp)
@@ -352,11 +354,19 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
 
 BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
-	setPauseState(true);
-	mScrollIndex = llclamp(	mScrollIndex + clicks,
-							0,
-							llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
-	return TRUE;
+    if (x < mBarRect.mLeft)
+    {
+        // Inside mScrollBar and list of timers
+        mScrollBar->handleScrollWheel(x,y,clicks);
+    }
+    else
+    {
+        setPauseState(true);
+        mScrollIndex = llclamp(mScrollIndex + clicks,
+            0,
+            llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
+    }
+    return TRUE;
 }
 
 static BlockTimerStatHandle FTM_RENDER_TIMER("Timers");
@@ -1197,6 +1207,7 @@ void LLFastTimerView::drawLegend()
 	{
 		LLLocalClipRect clip(mLegendRect);
 		S32 cur_line = 0;
+		S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect
 		ft_display_idx.clear();
 		std::map<BlockTimerStatHandle*, S32> display_line;
 		for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
@@ -1204,10 +1215,24 @@ void LLFastTimerView::drawLegend()
 			++it)
 		{
 			BlockTimerStatHandle* idp = (*it);
+			// Needed to figure out offsets and parenting
 			display_line[idp] = cur_line;
-			ft_display_idx.push_back(idp);
 			cur_line++;
+			if (scroll_offset < mScrollBar->getDocPos())
+			{
+				// only offset for visible items
+				scroll_offset += TEXT_HEIGHT + 2;
+				if (idp->getTreeNode().mCollapsed)
+				{
+					it.skipDescendants();
+				}
+				continue;
+			}
+
+			// used for mouse clicks
+			ft_display_idx.push_back(idp);
 
+			// Actual draw, first bar (square), then text
 			x = MARGIN;
 
 			LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT);
@@ -1281,11 +1306,14 @@ void LLFastTimerView::drawLegend()
 
 			y -= (TEXT_HEIGHT + 2);
 
+			scroll_offset += TEXT_HEIGHT + 2;
 			if (idp->getTreeNode().mCollapsed) 
 			{
 				it.skipDescendants();
 			}
 		}
+		// Recalculate scroll size
+		mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight());
 	}
 }
 
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 3e30bd86ba8bda4536cfbd134c8dc1430845ef3d..ff65f8da079988aaea6b2b6e4fbb15cba0a5c4eb 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -33,6 +33,8 @@
 #include "lltracerecording.h"
 #include <deque>
 
+class LLScrollbar;
+
 class LLFastTimerView : public LLFloater
 {
 public:
@@ -142,6 +144,8 @@ class LLFastTimerView : public LLFloater
 									mLegendRect;
 	LLFrameTimer					mHighlightTimer;
 	LLTrace::PeriodicRecording		mRecording;
+
+	LLScrollbar* 					mScrollBar;
 };
 
 #endif
diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp
deleted file mode 100644
index e84cbc289f2d6377ebc6886023803d116397164f..0000000000000000000000000000000000000000
--- a/indra/newview/llfloaterfacebook.cpp
+++ /dev/null
@@ -1,1132 +0,0 @@
-/**
-* @file llfloaterfacebook.cpp
-* @brief Implementation of llfloaterfacebook
-* @author Gilbert@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterfacebook.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llfacebookconnect.h"
-#include "llfloaterbigpreview.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h"		// LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "llavatarlist.h"
-#include "llpanelpeoplemenus.h"
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-
-static LLPanelInjector<LLFacebookStatusPanel> t_panel_status("llfacebookstatuspanel");
-static LLPanelInjector<LLFacebookPhotoPanel> t_panel_photo("llfacebookphotopanel");
-static LLPanelInjector<LLFacebookCheckinPanel> t_panel_checkin("llfacebookcheckinpanel");
-static LLPanelInjector<LLFacebookFriendsPanel> t_panel_friends("llfacebookfriendspanel");
-
-const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/";
-const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazonaws.com/map_placeholder.png";
-const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare";
-
-const S32 MAX_QUALITY = 100;         // Max quality value for jpeg images
-const S32 MIN_QUALITY = 0;           // Min quality value for jpeg images
-const S32 TARGET_DATA_SIZE = 950000; // Size of the image (compressed) we're trying to send to Facebook
-
-std::string get_map_url()
-{
-    LLVector3d center_agent;
-    LLViewerRegion *regionp = gAgent.getRegion();
-    if (regionp)
-    {
-        center_agent = regionp->getCenterGlobal();
-    }
-    int x_pos = center_agent[0] / 256.0;
-    int y_pos = center_agent[1] / 256.0;
-    std::string map_url = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-1-%d-%d-objects.jpg", x_pos, y_pos);
-    return map_url;
-}
-
-// Compute target jpeg quality : see https://wiki.lindenlab.com/wiki/Facebook_Image_Quality for details
-S32 compute_jpeg_quality(S32 width, S32 height)
-{
-    F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE);
-    S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio));
-    return llclamp(quality, MIN_QUALITY, MAX_QUALITY);
-}
-
-///////////////////////////
-//LLFacebookStatusPanel//////
-///////////////////////////
-
-LLFacebookStatusPanel::LLFacebookStatusPanel() :
-    mMessageTextEditor(NULL),
-    mPostButton(NULL),
-    mCancelButton(NULL),
-    mAccountCaptionLabel(NULL),
-    mAccountNameLabel(NULL),
-    mPanelButtons(NULL),
-    mConnectButton(NULL),
-    mDisconnectButton(NULL)
-{
-    mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this));
-    mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this));
-
-    setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2));
-
-    mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this));
-}
-
-BOOL LLFacebookStatusPanel::postBuild()
-{
-    mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
-    mAccountNameLabel = getChild<LLTextBox>("account_name_label");
-    mPanelButtons = getChild<LLUICtrl>("panel_buttons");
-    mConnectButton = getChild<LLUICtrl>("connect_btn");
-    mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
-    mMessageTextEditor = getChild<LLUICtrl>("status_message");
-    mPostButton = getChild<LLUICtrl>("post_status_btn");
-    mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
-
-    return LLPanel::postBuild();
-}
-
-void LLFacebookStatusPanel::draw()
-{
-    LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
-
-    //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
-    bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
-    mDisconnectButton->setEnabled(!disconnecting);
-
-    //Disable the 'connect' button when a connection is in progress
-    bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
-    mConnectButton->setEnabled(!connecting);
-
-    if (mMessageTextEditor && mPostButton && mCancelButton)
-    {
-        bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
-        std::string message = mMessageTextEditor->getValue().asString();
-        mMessageTextEditor->setEnabled(no_ongoing_connection);
-        mCancelButton->setEnabled(no_ongoing_connection);
-        mPostButton->setEnabled(no_ongoing_connection && !message.empty());
-    }
-
-    LLPanel::draw();
-}
-
-void LLFacebookStatusPanel::onSend()
-{
-    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening
-    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1));
-
-    // Connect to Facebook if necessary and then post
-    if (LLFacebookConnect::instance().isConnected())
-    {
-        sendStatus();
-    }
-    else
-    {
-        LLFacebookConnect::instance().checkConnectionToFacebook(true);
-    }
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectStateChange(const LLSD& data)
-{
-    switch (data.get("enum").asInteger())
-    {
-    case LLFacebookConnect::FB_CONNECTED:
-        sendStatus();
-        break;
-
-    case LLFacebookConnect::FB_POSTED:
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel");
-        clearAndClose();
-        break;
-    }
-
-    return false;
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectAccountStateChange(const LLSD& data)
-{
-    if (LLFacebookConnect::instance().isConnected())
-    {
-        //In process of disconnecting so leave the layout as is
-        if (data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
-        {
-            showConnectedLayout();
-        }
-    }
-    else
-    {
-        showDisconnectedLayout();
-    }
-
-    return false;
-}
-
-void LLFacebookStatusPanel::sendStatus()
-{
-    std::string message = mMessageTextEditor->getValue().asString();
-    if (!message.empty())
-    {
-        LLFacebookConnect::instance().updateStatus(message);
-    }
-}
-
-void LLFacebookStatusPanel::onVisibilityChange(BOOL visible)
-{
-    if (visible)
-    {
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
-        LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1));
-
-        LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
-        LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this));
-
-        //Connected
-        if (LLFacebookConnect::instance().isConnected())
-        {
-            showConnectedLayout();
-        }
-        //Check if connected (show disconnected layout in meantime)
-        else
-        {
-            showDisconnectedLayout();
-        }
-        if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
-            (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
-        {
-            LLFacebookConnect::instance().checkConnectionToFacebook();
-        }
-    }
-    else
-    {
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
-        LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
-    }
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectInfoChange()
-{
-    LLSD info = LLFacebookConnect::instance().getInfo();
-    std::string clickable_name;
-
-    //Strings of format [http://www.somewebsite.com Click Me] become clickable text
-    if (info.has("link") && info.has("name"))
-    {
-        clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
-    }
-
-    mAccountNameLabel->setText(clickable_name);
-
-    return false;
-}
-
-void LLFacebookStatusPanel::showConnectButton()
-{
-    if (!mConnectButton->getVisible())
-    {
-        mConnectButton->setVisible(TRUE);
-        mDisconnectButton->setVisible(FALSE);
-    }
-}
-
-void LLFacebookStatusPanel::hideConnectButton()
-{
-    if (mConnectButton->getVisible())
-    {
-        mConnectButton->setVisible(FALSE);
-        mDisconnectButton->setVisible(TRUE);
-    }
-}
-
-void LLFacebookStatusPanel::showDisconnectedLayout()
-{
-    mAccountCaptionLabel->setText(getString("facebook_disconnected"));
-    mAccountNameLabel->setText(std::string(""));
-    showConnectButton();
-}
-
-void LLFacebookStatusPanel::showConnectedLayout()
-{
-    LLFacebookConnect::instance().loadFacebookInfo();
-
-    mAccountCaptionLabel->setText(getString("facebook_connected"));
-    hideConnectButton();
-}
-
-void LLFacebookStatusPanel::onConnect()
-{
-    LLFacebookConnect::instance().checkConnectionToFacebook(true);
-}
-
-void LLFacebookStatusPanel::onDisconnect()
-{
-    LLFacebookConnect::instance().disconnectFromFacebook();
-}
-
-void LLFacebookStatusPanel::clearAndClose()
-{
-    mMessageTextEditor->setValue("");
-
-    LLFloater* floater = getParentByType<LLFloater>();
-    if (floater)
-    {
-        floater->closeFloater();
-    }
-}
-
-///////////////////////////
-//LLFacebookPhotoPanel///////
-///////////////////////////
-
-LLFacebookPhotoPanel::LLFacebookPhotoPanel() :
-    mResolutionComboBox(NULL),
-    mRefreshBtn(NULL),
-    mBtnPreview(NULL),
-    mWorkingLabel(NULL),
-    mThumbnailPlaceholder(NULL),
-    mCaptionTextBox(NULL),
-    mPostButton(NULL),
-    mBigPreviewFloater(NULL),
-    mQuality(MAX_QUALITY)
-{
-    mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this));
-    mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this));
-    mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this));
-}
-
-LLFacebookPhotoPanel::~LLFacebookPhotoPanel()
-{
-    if (mPreviewHandle.get())
-    {
-        mPreviewHandle.get()->die();
-    }
-}
-
-BOOL LLFacebookPhotoPanel::postBuild()
-{
-    setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2));
-
-    mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
-    mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw!
-    mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
-    mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
-    mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
-    mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
-    mBtnPreview = getChild<LLButton>("big_preview_btn");
-    mWorkingLabel = getChild<LLUICtrl>("working_lbl");
-    mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
-    mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
-    mPostButton = getChild<LLUICtrl>("post_photo_btn");
-    mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
-    mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
-    // Update filter list
-    std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
-    LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-    for (U32 i = 0; i < filter_list.size(); i++)
-    {
-        filterbox->add(filter_list[i]);
-    }
-
-    return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLFacebookPhotoPanel::notify(const LLSD& info)
-{
-    if (info.has("snapshot-updating"))
-    {
-        // Disable the Post button and whatever else while the snapshot is not updated
-        // updateControls();
-        return 1;
-    }
-
-    if (info.has("snapshot-updated"))
-    {
-        // Enable the send/post/save buttons.
-        updateControls();
-
-        // The refresh button is initially hidden. We show it after the first update,
-        // i.e. after snapshot is taken
-        LLUICtrl * refresh_button = getRefreshBtn();
-        if (!refresh_button->getVisible())
-        {
-            refresh_button->setVisible(true);
-        }
-        return 1;
-    }
-
-    return 0;
-}
-
-void LLFacebookPhotoPanel::draw()
-{
-    LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
-    // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
-    bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
-    mCancelButton->setEnabled(no_ongoing_connection);
-    mCaptionTextBox->setEnabled(no_ongoing_connection);
-    mResolutionComboBox->setEnabled(no_ongoing_connection);
-    mFilterComboBox->setEnabled(no_ongoing_connection);
-    mRefreshBtn->setEnabled(no_ongoing_connection);
-    mBtnPreview->setEnabled(no_ongoing_connection);
-
-    // Reassign the preview floater if we have the focus and the preview exists
-    if (hasFocus() && isPreviewVisible())
-    {
-        attachPreview();
-    }
-
-    // Toggle the button state as appropriate
-    bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
-    mBtnPreview->setToggleState(preview_active);
-
-    // Display the thumbnail if one is available
-    if (previewp && previewp->getThumbnailImage())
-    {
-        const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
-        const S32 thumbnail_w = previewp->getThumbnailWidth();
-        const S32 thumbnail_h = previewp->getThumbnailHeight();
-
-        // calc preview offset within the preview rect
-        const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2;
-        const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2;
-        S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
-        S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
-        gGL.matrixMode(LLRender::MM_MODELVIEW);
-        // Apply floater transparency to the texture unless the floater is focused.
-        F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-        LLColor4 color = LLColor4::white;
-        gl_draw_scaled_image(offset_x, offset_y,
-            thumbnail_w, thumbnail_h,
-            previewp->getThumbnailImage(), color % alpha);
-    }
-
-    // Update the visibility of the working (computing preview) label
-    mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
-    // Enable Post if we have a preview to send and no on going connection being processed
-    mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
-
-    // Draw the rest of the panel on top of it
-    LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLFacebookPhotoPanel::getPreviewView()
-{
-    LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
-    return previewp;
-}
-
-void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible)
-{
-    if (visible)
-    {
-        if (mPreviewHandle.get())
-        {
-            LLSnapshotLivePreview* preview = getPreviewView();
-            if (preview)
-            {
-                LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
-                preview->updateSnapshot(TRUE);
-            }
-        }
-        else
-        {
-            LLRect full_screen_rect = getRootView()->getRect();
-            LLSnapshotLivePreview::Params p;
-            p.rect(full_screen_rect);
-            LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
-            mPreviewHandle = previewp->getHandle();
-            mQuality = MAX_QUALITY;
-
-            previewp->setContainer(this);
-            previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
-            previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
-            previewp->setSnapshotQuality(mQuality, false);
-            previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
-            previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
-            previewp->setAllowFullScreenPreview(FALSE);  // No full screen preview in SL Share mode
-            previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
-            updateControls();
-        }
-    }
-}
-
-void LLFacebookPhotoPanel::onClickNewSnapshot()
-{
-    LLSnapshotLivePreview* previewp = getPreviewView();
-    if (previewp)
-    {
-        previewp->updateSnapshot(TRUE);
-    }
-}
-
-void LLFacebookPhotoPanel::onClickBigPreview()
-{
-    // Toggle the preview
-    if (isPreviewVisible())
-    {
-        LLFloaterReg::hideInstance("big_preview");
-    }
-    else
-    {
-        attachPreview();
-        LLFloaterReg::showInstance("big_preview");
-    }
-}
-
-bool LLFacebookPhotoPanel::isPreviewVisible()
-{
-    return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLFacebookPhotoPanel::attachPreview()
-{
-    if (mBigPreviewFloater)
-    {
-        LLSnapshotLivePreview* previewp = getPreviewView();
-        mBigPreviewFloater->setPreview(previewp);
-        mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
-    }
-}
-
-void LLFacebookPhotoPanel::onSend()
-{
-    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening
-    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1));
-
-    // Connect to Facebook if necessary and then post
-    if (LLFacebookConnect::instance().isConnected())
-    {
-        sendPhoto();
-    }
-    else
-    {
-        LLFacebookConnect::instance().checkConnectionToFacebook(true);
-    }
-}
-
-bool LLFacebookPhotoPanel::onFacebookConnectStateChange(const LLSD& data)
-{
-    switch (data.get("enum").asInteger())
-    {
-    case LLFacebookConnect::FB_CONNECTED:
-        sendPhoto();
-        break;
-
-    case LLFacebookConnect::FB_POSTED:
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel");
-        clearAndClose();
-        break;
-    }
-
-    return false;
-}
-
-void LLFacebookPhotoPanel::sendPhoto()
-{
-    // Get the caption
-    std::string caption = mCaptionTextBox->getValue().asString();
-
-    // Get the image
-    LLSnapshotLivePreview* previewp = getPreviewView();
-
-    // Post to Facebook
-    LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
-
-    updateControls();
-}
-
-void LLFacebookPhotoPanel::clearAndClose()
-{
-    mCaptionTextBox->setValue("");
-
-    LLFloater* floater = getParentByType<LLFloater>();
-    if (floater)
-    {
-        floater->closeFloater();
-        if (mBigPreviewFloater)
-        {
-            mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
-        }
-    }
-}
-
-void LLFacebookPhotoPanel::updateControls()
-{
-    LLSnapshotLivePreview* previewp = getPreviewView();
-    BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
-    // *TODO: Separate maximum size for Web images from postcards
-    LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
-    updateResolution(FALSE);
-}
-
-void LLFacebookPhotoPanel::updateResolution(BOOL do_update)
-{
-    LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
-    LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
-    std::string sdstring = combobox->getSelectedValue();
-    LLSD sdres;
-    std::stringstream sstream(sdstring);
-    LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
-    S32 width = sdres[0];
-    S32 height = sdres[1];
-
-    // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
-    std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
-    LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-    if (previewp && combobox->getCurrentIndex() >= 0)
-    {
-        S32 original_width = 0, original_height = 0;
-        previewp->getSize(original_width, original_height);
-
-        if (width == 0 || height == 0)
-        {
-            // take resolution from current window size
-            LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
-            previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
-        }
-        else
-        {
-            // use the resolution from the selected pre-canned drop-down choice
-            LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
-            previewp->setSize(width, height);
-        }
-
-        checkAspectRatio(width);
-
-        previewp->getSize(width, height);
-
-        // Recompute quality setting
-        mQuality = compute_jpeg_quality(width, height);
-        previewp->setSnapshotQuality(mQuality, false);
-
-        if (original_width != width || original_height != height)
-        {
-            previewp->setSize(width, height);
-            if (do_update)
-            {
-                previewp->updateSnapshot(TRUE);
-                updateControls();
-            }
-        }
-        // Get the old filter, compare to the current one "filter_name" and set if changed
-        std::string original_filter = previewp->getFilter();
-        if (original_filter != filter_name)
-        {
-            previewp->setFilter(filter_name);
-            if (do_update)
-            {
-                previewp->updateSnapshot(FALSE, TRUE);
-                updateControls();
-            }
-        }
-    }
-}
-
-void LLFacebookPhotoPanel::checkAspectRatio(S32 index)
-{
-    LLSnapshotLivePreview *previewp = getPreviewView();
-
-    BOOL keep_aspect = FALSE;
-
-    if (0 == index) // current window size
-    {
-        keep_aspect = TRUE;
-    }
-    else // predefined resolution
-    {
-        keep_aspect = FALSE;
-    }
-
-    if (previewp)
-    {
-        previewp->mKeepAspectRatio = keep_aspect;
-    }
-}
-
-LLUICtrl* LLFacebookPhotoPanel::getRefreshBtn()
-{
-    return mRefreshBtn;
-}
-
-////////////////////////
-//LLFacebookCheckinPanel//
-////////////////////////
-
-LLFacebookCheckinPanel::LLFacebookCheckinPanel() :
-    mMapUrl(""),
-    mReloadingMapTexture(false)
-{
-    mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this));
-}
-
-BOOL LLFacebookCheckinPanel::postBuild()
-{
-    // Keep pointers to widgets so we don't traverse the UI hierarchy too often
-    mPostButton = getChild<LLUICtrl>("post_place_btn");
-    mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
-    mMessageTextEditor = getChild<LLUICtrl>("place_caption");
-    mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator");
-    mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder");
-    mMapDefault = getChild<LLIconCtrl>("map_default");
-    mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb");
-
-    return LLPanel::postBuild();
-}
-
-void LLFacebookCheckinPanel::draw()
-{
-    bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
-    mPostButton->setEnabled(no_ongoing_connection);
-    mCancelButton->setEnabled(no_ongoing_connection);
-    mMessageTextEditor->setEnabled(no_ongoing_connection);
-    mMapCheckBox->setEnabled(no_ongoing_connection);
-
-    std::string map_url = get_map_url();
-    // Did we change location?
-    if (map_url != mMapUrl)
-    {
-        mMapUrl = map_url;
-        // Load the map tile
-        mMapTexture = LLViewerTextureManager::getFetchedTextureFromUrl(mMapUrl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-        mMapTexture->setBoostLevel(LLGLTexture::BOOST_MAP);
-        mReloadingMapTexture = true;
-        // In the meantime, put the "loading" indicator on, hide the tile map and disable the checkbox
-        mMapLoadingIndicator->setVisible(true);
-        mMapPlaceholder->setVisible(false);
-    }
-    // Are we done loading the map tile?
-    if (mReloadingMapTexture && mMapTexture->isFullyLoaded())
-    {
-        // Don't do it again next time around
-        mReloadingMapTexture = false;
-        // Convert the map texture to the appropriate image object
-        LLPointer<LLUIImage> ui_image = new LLUIImage(mMapUrl, mMapTexture);
-        // Load the map widget with the correct map tile image
-        mMapPlaceholder->setImage(ui_image);
-        // Now hide the loading indicator, bring the tile in view and reenable the checkbox with its previous value
-        mMapLoadingIndicator->setVisible(false);
-        mMapPlaceholder->setVisible(true);
-    }
-    // Show the default icon if that's the checkbox value (the real one...)
-    // This will hide/show the loading indicator and/or tile underneath
-    mMapDefault->setVisible(!(mMapCheckBox->get()));
-
-    LLPanel::draw();
-}
-
-void LLFacebookCheckinPanel::onSend()
-{
-    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening
-    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1));
-
-    // Connect to Facebook if necessary and then post
-    if (LLFacebookConnect::instance().isConnected())
-    {
-        sendCheckin();
-    }
-    else
-    {
-        LLFacebookConnect::instance().checkConnectionToFacebook(true);
-    }
-}
-
-bool LLFacebookCheckinPanel::onFacebookConnectStateChange(const LLSD& data)
-{
-    switch (data.get("enum").asInteger())
-    {
-    case LLFacebookConnect::FB_CONNECTED:
-        sendCheckin();
-        break;
-
-    case LLFacebookConnect::FB_POSTED:
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel");
-        clearAndClose();
-        break;
-    }
-
-    return false;
-}
-
-void LLFacebookCheckinPanel::sendCheckin()
-{
-    // Get the location SLURL
-    LLSLURL slurl;
-    LLAgentUI::buildSLURL(slurl);
-    std::string slurl_string = slurl.getSLURLString();
-
-    // Use a valid http:// URL if the scheme is secondlife://
-    LLURI slurl_uri(slurl_string);
-    if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
-    {
-        slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
-    }
-
-    // Add query parameters so Google Analytics can track incoming clicks!
-    slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
-
-    // Get the region name
-    std::string region_name("");
-    LLViewerRegion *regionp = gAgent.getRegion();
-    if (regionp)
-    {
-        region_name = regionp->getName();
-    }
-
-    // Get the region description
-    std::string description;
-    LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
-
-    // Optionally add the region map view
-    bool add_map_view = mMapCheckBox->getValue().asBoolean();
-    std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL);
-
-    // Get the caption
-    std::string caption = mMessageTextEditor->getValue().asString();
-
-    // Post to Facebook
-    LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
-}
-
-void LLFacebookCheckinPanel::clearAndClose()
-{
-    mMessageTextEditor->setValue("");
-
-    LLFloater* floater = getParentByType<LLFloater>();
-    if (floater)
-    {
-        floater->closeFloater();
-    }
-}
-
-///////////////////////////
-//LLFacebookFriendsPanel//////
-///////////////////////////
-
-LLFacebookFriendsPanel::LLFacebookFriendsPanel() :
-    mFriendsStatusCaption(NULL),
-    mSecondLifeFriends(NULL),
-    mSuggestedFriends(NULL)
-{
-}
-
-LLFacebookFriendsPanel::~LLFacebookFriendsPanel()
-{
-    LLAvatarTracker::instance().removeObserver(this);
-}
-
-BOOL LLFacebookFriendsPanel::postBuild()
-{
-    mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status");
-
-    mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends");
-    mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
-
-    mSuggestedFriends = getChild<LLAvatarList>("suggested_friends");
-    mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
-
-    setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2));
-
-    LLAvatarTracker::instance().addObserver(this);
-
-    return LLPanel::postBuild();
-}
-
-bool LLFacebookFriendsPanel::updateSuggestedFriendList()
-{
-    const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
-    uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs();
-    second_life_friends.clear();
-    uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
-    suggested_friends.clear();
-
-    //Add suggested friends
-    LLSD friends = LLFacebookConnect::instance().getContent();
-    for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
-    {
-        LLUUID agent_id = (*i).asUUID();
-        if (agent_id.notNull())
-        {
-            bool second_life_buddy = av_tracker.isBuddy(agent_id);
-            if (second_life_buddy)
-            {
-                second_life_friends.push_back(agent_id);
-            }
-            else
-            {
-                //FB+SL but not SL friend
-                suggested_friends.push_back(agent_id);
-            }
-        }
-    }
-
-    //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
-    mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches());
-    mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
-    showFriendsAccordionsIfNeeded();
-
-    return false;
-}
-
-void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded()
-{
-    // Show / hide the status text : needs to be done *before* showing / hidding the accordions
-    if (!mSecondLifeFriends->filterHasMatches() && !mSuggestedFriends->filterHasMatches())
-    {
-        // Show some explanation text if the lists are empty...
-        mFriendsStatusCaption->setVisible(true);
-        if (LLFacebookConnect::instance().isConnected())
-        {
-            //...you're connected to FB but have no friends :(
-            mFriendsStatusCaption->setText(getString("facebook_friends_empty"));
-        }
-        else
-        {
-            //...you're not connected to FB
-            mFriendsStatusCaption->setText(getString("facebook_friends_no_connected"));
-        }
-        // Hide the lists
-        getChild<LLAccordionCtrl>("friends_accordion")->setVisible(false);
-        getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(false);
-        getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(false);
-    }
-    else
-    {
-        // We have something in the lists, hide the explanatory text
-        mFriendsStatusCaption->setVisible(false);
-
-        // Show the lists
-        LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
-        accordion->setVisible(true);
-
-        // Expand and show accordions if needed, else - hide them
-        getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(mSecondLifeFriends->filterHasMatches());
-        getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(mSuggestedFriends->filterHasMatches());
-
-        // Rearrange accordions
-        accordion->arrange();
-    }
-}
-
-void LLFacebookFriendsPanel::changed(U32 mask)
-{
-    if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
-    {
-        LLFacebookConnect::instance().loadFacebookFriends();
-        updateFacebookList(true);
-    }
-}
-
-
-void LLFacebookFriendsPanel::updateFacebookList(bool visible)
-{
-    if (visible)
-    {
-        // We want this to be called to fetch the friends list once a connection is established
-        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel");
-        LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1));
-
-        // We then want this to be called to update the displayed lists once the list of friends is received
-        LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening
-        LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this));
-
-        // Try to connect to Facebook
-        if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
-            (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
-        {
-            LLFacebookConnect::instance().checkConnectionToFacebook();
-        }
-        // Loads FB friends
-        if (LLFacebookConnect::instance().isConnected())
-        {
-            LLFacebookConnect::instance().loadFacebookFriends();
-        }
-        // Sort the FB friends and update the lists
-        updateSuggestedFriendList();
-    }
-}
-
-bool LLFacebookFriendsPanel::onConnectedToFacebook(const LLSD& data)
-{
-    LLSD::Integer connection_state = data.get("enum").asInteger();
-
-    if (connection_state == LLFacebookConnect::FB_CONNECTED)
-    {
-        LLFacebookConnect::instance().loadFacebookFriends();
-    }
-    else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
-    {
-        updateSuggestedFriendList();
-    }
-
-    return false;
-}
-
-////////////////////////
-//LLFloaterFacebook///////
-////////////////////////
-
-LLFloaterFacebook::LLFloaterFacebook(const LLSD& key) : LLFloater(key),
-    mFacebookPhotoPanel(NULL),
-    mStatusErrorText(NULL),
-    mStatusLoadingText(NULL),
-    mStatusLoadingIndicator(NULL)
-{
-    mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this));
-}
-
-void LLFloaterFacebook::onClose(bool app_quitting)
-{
-    LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-    if (big_preview_floater)
-    {
-        big_preview_floater->closeOnFloaterOwnerClosing(this);
-    }
-    LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterFacebook::onCancel()
-{
-    LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-    if (big_preview_floater)
-    {
-        big_preview_floater->closeOnFloaterOwnerClosing(this);
-    }
-    closeFloater();
-}
-
-BOOL LLFloaterFacebook::postBuild()
-{
-    // Keep tab of the Photo Panel
-    mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo"));
-    // Connection status widgets
-    mStatusErrorText = getChild<LLTextBox>("connection_error_text");
-    mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
-    mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
-    return LLFloater::postBuild();
-}
-
-void LLFloaterFacebook::showPhotoPanel()
-{
-    LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent());
-    if (!parent)
-    {
-        LL_WARNS() << "Cannot find panel container" << LL_ENDL;
-        return;
-    }
-
-    parent->selectTabPanel(mFacebookPhotoPanel);
-}
-
-void LLFloaterFacebook::draw()
-{
-    if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
-    {
-        mStatusErrorText->setVisible(false);
-        mStatusLoadingText->setVisible(false);
-        mStatusLoadingIndicator->setVisible(false);
-        LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
-        std::string status_text;
-
-        switch (connection_state)
-        {
-        case LLFacebookConnect::FB_NOT_CONNECTED:
-            // No status displayed when first opening the panel and no connection done
-        case LLFacebookConnect::FB_CONNECTED:
-            // When successfully connected, no message is displayed
-        case LLFacebookConnect::FB_POSTED:
-            // No success message to show since we actually close the floater after successful posting completion
-            break;
-        case LLFacebookConnect::FB_CONNECTION_IN_PROGRESS:
-            // Connection loading indicator
-            mStatusLoadingText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookConnecting");
-            mStatusLoadingText->setValue(status_text);
-            mStatusLoadingIndicator->setVisible(true);
-            break;
-        case LLFacebookConnect::FB_POSTING:
-            // Posting indicator
-            mStatusLoadingText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookPosting");
-            mStatusLoadingText->setValue(status_text);
-            mStatusLoadingIndicator->setVisible(true);
-            break;
-        case LLFacebookConnect::FB_CONNECTION_FAILED:
-            // Error connecting to the service
-            mStatusErrorText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookErrorConnecting");
-            mStatusErrorText->setValue(status_text);
-            break;
-        case LLFacebookConnect::FB_POST_FAILED:
-            // Error posting to the service
-            mStatusErrorText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookErrorPosting");
-            mStatusErrorText->setValue(status_text);
-            break;
-        case LLFacebookConnect::FB_DISCONNECTING:
-            // Disconnecting loading indicator
-            mStatusLoadingText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookDisconnecting");
-            mStatusLoadingText->setValue(status_text);
-            mStatusLoadingIndicator->setVisible(true);
-            break;
-        case LLFacebookConnect::FB_DISCONNECT_FAILED:
-            // Error disconnecting from the service
-            mStatusErrorText->setVisible(true);
-            status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
-            mStatusErrorText->setValue(status_text);
-            break;
-        }
-    }
-    LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloaterfacebook.h b/indra/newview/llfloaterfacebook.h
deleted file mode 100644
index a4ca666b200531bc21135d3a00a90ddeb01f980e..0000000000000000000000000000000000000000
--- a/indra/newview/llfloaterfacebook.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/** 
-* @file   llfloaterfacebook.h
-* @brief  Header file for llfloaterfacebook
-* @author Gilbert@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERFACEBOOK_H
-#define LL_LLFLOATERFACEBOOK_H
-
-#include "llcallingcard.h"
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLAvatarList;
-class LLFloaterBigPreview;
-
-class LLFacebookStatusPanel : public LLPanel
-{
-public:
-    LLFacebookStatusPanel();
-	BOOL postBuild();
-	void draw();
-    void onSend();
-	bool onFacebookConnectStateChange(const LLSD& data);
-	bool onFacebookConnectAccountStateChange(const LLSD& data);
-
-	void sendStatus();
-	void clearAndClose();
-
-private:
-	void onVisibilityChange(BOOL new_visibility);
-	bool onFacebookConnectInfoChange();
-	void onConnect();
-	void onUseAnotherAccount();
-	void onDisconnect();
-
-	void showConnectButton();
-	void hideConnectButton();
-	void showDisconnectedLayout();
-	void showConnectedLayout();
-
-	LLTextBox * mAccountCaptionLabel;
-	LLTextBox * mAccountNameLabel;
-	LLUICtrl * mPanelButtons;
-	LLUICtrl * mConnectButton;
-	LLUICtrl * mDisconnectButton;
-	LLUICtrl* mMessageTextEditor;
-	LLUICtrl* mPostButton;
-	LLUICtrl* mCancelButton;
-};
-
-class LLFacebookPhotoPanel : public LLPanel
-{
-public:
-	LLFacebookPhotoPanel();
-	~LLFacebookPhotoPanel();
-
-	BOOL postBuild();
-	void draw();
-
-	LLSnapshotLivePreview* getPreviewView();
-	void onVisibilityChange(BOOL new_visibility);
-    void onClickBigPreview();
-	void onClickNewSnapshot();
-	void onSend();
-	S32 notify(const LLSD& info);
-	bool onFacebookConnectStateChange(const LLSD& data);
-
-	void sendPhoto();
-	void clearAndClose();
-
-	void updateControls();
-	void updateResolution(BOOL do_update);
-	void checkAspectRatio(S32 index);
-	LLUICtrl* getRefreshBtn();
-
-private:
-    bool isPreviewVisible();
-    void attachPreview();
-    
-	LLHandle<LLView> mPreviewHandle;
-
-	LLUICtrl * mResolutionComboBox;
-	LLUICtrl * mFilterComboBox;
-	LLUICtrl * mRefreshBtn;
-	LLUICtrl * mWorkingLabel;
-	LLUICtrl * mThumbnailPlaceholder;
-	LLUICtrl * mCaptionTextBox;
-	LLUICtrl * mPostButton;
-	LLUICtrl * mCancelButton;
-	LLButton * mBtnPreview;
-    
-    LLFloaterBigPreview * mBigPreviewFloater;
-    
-    S32 mQuality;       // Compression quality
-};
-
-class LLFacebookCheckinPanel : public LLPanel
-{
-public:
-    LLFacebookCheckinPanel();
-	BOOL postBuild();
-	void draw();
-    void onSend();
-	bool onFacebookConnectStateChange(const LLSD& data);
-
-	void sendCheckin();
-	void clearAndClose();
-
-private:
-    std::string mMapUrl;
-    LLPointer<LLViewerFetchedTexture> mMapTexture;
-	LLUICtrl* mPostButton;
-	LLUICtrl* mCancelButton;
-	LLUICtrl* mMessageTextEditor;
-    LLUICtrl* mMapLoadingIndicator;
-    LLIconCtrl* mMapPlaceholder;
-    LLIconCtrl* mMapDefault;
-    LLCheckBoxCtrl* mMapCheckBox;
-    bool mReloadingMapTexture;
-};
-
-class LLFacebookFriendsPanel : public LLPanel, public LLFriendObserver
-{
-public:
-	LLFacebookFriendsPanel();
-	~LLFacebookFriendsPanel();
-	BOOL postBuild();
-	virtual void changed(U32 mask);
-
-private:
-	bool updateSuggestedFriendList();
-	void showFriendsAccordionsIfNeeded();
-	void updateFacebookList(bool visible);
-	bool onConnectedToFacebook(const LLSD& data);
-	
-	LLTextBox * mFriendsStatusCaption;
-	LLAvatarList* mSecondLifeFriends;
-	LLAvatarList* mSuggestedFriends;
-};
-
-class LLFloaterFacebook : public LLFloater
-{
-public:
-	LLFloaterFacebook(const LLSD& key);
-	BOOL postBuild();
-	void draw();
-	void onClose(bool app_quitting);
-	void onCancel();
-	
-	void showPhotoPanel();
-
-private:
-	LLFacebookPhotoPanel* mFacebookPhotoPanel;
-    LLTextBox* mStatusErrorText;
-    LLTextBox* mStatusLoadingText;
-    LLUICtrl*  mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERFACEBOOK_H
-
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 7f2e8fd82a2707e1af9d7878a349cb2f53e11422..3098c6d11831c941fd2d769dadd3cb55df5b462a 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1877,6 +1877,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
 	mLandingTypeCombo(NULL),
 	mSnapshotCtrl(NULL),
 	mLocationText(NULL),
+	mSeeAvatarsText(NULL),
 	mSetBtn(NULL),
 	mClearBtn(NULL),
 	mMatureCtrl(NULL),
@@ -1923,6 +1924,14 @@ BOOL LLPanelLandOptions::postBuild()
 	mSeeAvatarsCtrl = getChild<LLCheckBoxCtrl>( "SeeAvatarsCheck");
 	childSetCommitCallback("SeeAvatarsCheck", onCommitAny, this);
 
+	mSeeAvatarsText = getChild<LLTextBox>("allow_see_label");
+	if (mSeeAvatarsText)
+	{
+		mSeeAvatarsText->setShowCursorHand(false);
+		mSeeAvatarsText->setSoundFlags(LLView::MOUSE_UP);
+		mSeeAvatarsText->setClickedCallback(boost::bind(&toggleSeeAvatars, this));
+	}
+
 	mCheckShowDirectory = getChild<LLCheckBoxCtrl>( "ShowDirectoryCheck");
 	childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
 
@@ -2016,6 +2025,7 @@ void LLPanelLandOptions::refresh()
 
 		mSeeAvatarsCtrl->set(TRUE);
 		mSeeAvatarsCtrl->setEnabled(FALSE);
+		mSeeAvatarsText->setEnabled(FALSE);
 
 		mLandingTypeCombo->setCurrentByIndex(0);
 		mLandingTypeCombo->setEnabled(FALSE);
@@ -2074,6 +2084,7 @@ void LLPanelLandOptions::refresh()
 
 		mSeeAvatarsCtrl->set(parcel->getSeeAVs());
 		mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
+		mSeeAvatarsText->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
 
 		BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, 
 														GP_LAND_SET_LANDING_POINT);
@@ -2364,7 +2375,16 @@ void LLPanelLandOptions::onClickClear(void* userdata)
 	self->refresh();
 }
 
-
+void LLPanelLandOptions::toggleSeeAvatars(void* userdata)
+{
+	LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
+	if (self)
+	{
+		self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->toggle();
+		self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->setBtnFocus();
+		self->onCommitAny(NULL, userdata);
+	}
+}
 //---------------------------------------------------------------------------
 // LLPanelLandAccess
 //---------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index e846d426665a219d14e8416ba15d73884b3f147b..0c49d78a20974f15b48db0a7ed8c61647acee935 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -327,6 +327,7 @@ class LLPanelLandOptions
 	static void onCommitAny(LLUICtrl* ctrl, void *userdata);
 	static void onClickSet(void* userdata);
 	static void onClickClear(void* userdata);
+	static void toggleSeeAvatars(void* userdata);
 
 private:
 	LLCheckBoxCtrl*	mCheckEditObjects;
@@ -345,6 +346,7 @@ class LLPanelLandOptions
 	LLTextureCtrl*	mSnapshotCtrl;
 
 	LLTextBox*		mLocationText;
+	LLTextBox*		mSeeAvatarsText;
 	LLButton*		mSetBtn;
 	LLButton*		mClearBtn;
 
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 5a27f3c3250529e90bfe83c70a5bfc89f91e0242..b6efc1590ea3ec51d40fa3908510850b65df024c 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -325,6 +325,8 @@ BOOL LLFloaterModelPreview::postBuild()
 	childSetCommitCallback("import_scale", onImportScaleCommit, this);
 	childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
 
+	getChild<LLLineEditor>("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL);
+
 	getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
 	getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
 	getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
@@ -520,6 +522,16 @@ void LLFloaterModelPreview::onClickCalculateBtn()
 	mUploadBtn->setEnabled(false);
 }
 
+void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
+{
+	// Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
+	LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
+	if (input->isDirty()) // dirty will be reset after commit
+	{
+		toggleCalculateButton(true);
+	}
+}
+
 //static
 void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
 {
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 7ec6a58ac76de31e44812a630f19edbc3b961307..edc90d1695176aa3859ff656e84daef8b9d97c5b 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -137,7 +137,9 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase
 	friend class LLModelPreview;
 	friend class LLMeshFilePicker;
 	friend class LLPhysicsDecomp;
-	
+
+	void		onDescriptionKeystroke(LLUICtrl*);
+
 	static void		onImportScaleCommit(LLUICtrl*, void*);
 	static void		onPelvisOffsetCommit(LLUICtrl*, void*);
 	static void		onUploadJointsCommit(LLUICtrl*,void*);
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index d80793f9e4286ad707ab79bfaa1e6ff1af0b43b4..bfcd1b8b472407029f11a919935cda29b250f76f 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -30,9 +30,7 @@
 #include "llfloateroutfitsnapshot.h"
 
 #include "llagent.h"
-#include "llfacebookconnect.h"
 #include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
 #include "llfloaterflickr.h"
 #include "llfloatertwitter.h"
 #include "llimagefiltersmanager.h"
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index a7931137b0b9cf59b55f5586a83cd366c689d9f1..2798e375c7c7cbeeb35cfcc44703f764ad8fcfc9 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -28,9 +28,7 @@
 
 #include "llfloatersnapshot.h"
 
-#include "llfacebookconnect.h"
 #include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
 #include "llfloaterflickr.h"
 #include "llfloatertwitter.h"
 #include "llimagefiltersmanager.h"
@@ -1242,11 +1240,10 @@ BOOL LLFloaterSnapshot::isWaitingState()
 
 BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
 {
-	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
 	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
 	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
 
-	if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter)
+	if (!initialized && !floater_flickr && !floater_twitter)
 		return FALSE;
 
 	BOOL changed = FALSE;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index ee4fdbe9a5ef3646a33fe33a1ec1b51803b36d35..c2c15ee12b59e7b597ae3754ba11ebe4b01b1cee 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -514,11 +514,6 @@ void LLFloaterTools::refresh()
 		selection_info << getString("status_selectcount", selection_args);
 
 		getChild<LLTextBox>("selection_count")->setText(selection_info.str());
-
-		bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
-		childSetVisible("selection_count",  have_selection);
-		childSetVisible("remaining_capacity", have_selection);
-		childSetVisible("selection_empty", !have_selection);
 	}
 
 
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 224e30f7de58a95fb1dc2e019eb9435d24ae72e4..c591dfacaf310c61204a318e39ceeb8041026a00 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -30,7 +30,6 @@
 #include "lliconctrl.h"
 #include "llfloaterreg.h"
 #include "llhttpconstants.h"
-#include "llfacebookconnect.h"
 #include "llflickrconnect.h"
 #include "lltwitterconnect.h"
 #include "lllayoutstack.h"
@@ -289,17 +288,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
 //virtual
 void LLFloaterWebContent::onClose(bool app_quitting)
 {
-    // If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
-	// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
-    LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web");
-    if (fbc_web == this)
-    {
-        if (!LLFacebookConnect::instance().isConnected())
-        {
-            LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
-        }
-    }
-	// Same with Flickr
+    // If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen
 	// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
 	LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
     if (flickr_web == this)
@@ -309,7 +298,7 @@ void LLFloaterWebContent::onClose(bool app_quitting)
             LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
         }
     }
-	// And Twitter
+	// Same with Twitter
 	// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
 	LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
     if (twitter_web == this)
@@ -380,13 +369,6 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
 		// The browser instance wants its window closed.
 		closeFloater();
 	}
-	else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
-	{
-		if (mCurrentURL.find("facebook.com/dialog/oauth") == std::string::npos) // HACK to fix ACME-1317 - Cho
-		{
-		geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
-	}
-	}
 	else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
 	{
 		const std::string text = self->getStatusText();
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index a9b15fc8b6296aa507bfd2759a6475a628db8aa2..fea01786f35796454d72091d74678fe6b9646242 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -1005,7 +1005,10 @@ F32 gpu_benchmark()
 
 	//number of samples to take
 	const S32 samples = 64;
-		
+
+	//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
+	const F32 time_limit = 30;
+
 	ShaderProfileHelper initProfile;
 	
 	std::vector<LLRenderTarget> dest(count);
@@ -1023,12 +1026,14 @@ F32 gpu_benchmark()
 	gGL.setColorMask(true, true);
 	LLGLDepthTest depth(GL_FALSE);
 
+	LLTimer alloc_timer;
+	alloc_timer.start();
 	for (U32 i = 0; i < count; ++i)
 	{
 		//allocate render targets and textures
 		if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
 		{
-			LL_WARNS() << "Failed to allocate render target." << LL_ENDL;
+			LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL;
 			// abandon the benchmark test
 			delete[] pixels;
 			return -1.f;
@@ -1040,12 +1045,20 @@ F32 gpu_benchmark()
 		if (!texHolder.bind(i))
 		{
 			// can use a dummy value mDummyTexUnit = new LLTexUnit(-1);
-			LL_WARNS() << "Failed to bind tex unit." << LL_ENDL;
+			LL_WARNS("Benchmark") << "Failed to bind tex unit." << LL_ENDL;
 			// abandon the benchmark test
 			delete[] pixels;
 			return -1.f;
 		}
 		LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+		if (alloc_timer.getElapsedTimeF32() > time_limit)
+		{
+			// abandon the benchmark test
+			LL_WARNS("Benchmark") << "Allocation operation took longer then 30 seconds, stopping." << LL_ENDL;
+			delete[] pixels;
+			return -1.f;
+		}
 	}
 
     delete [] pixels;
@@ -1055,7 +1068,7 @@ F32 gpu_benchmark()
 
 	if (!buff->allocateBuffer(3, 0, true))
 	{
-		LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL;
+		LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL;
 		// abandon the benchmark test
 		return -1.f;
 	}
@@ -1065,7 +1078,7 @@ F32 gpu_benchmark()
 
 	if (! buff->getVertexStrider(v))
 	{
-		LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, "
+		LL_WARNS("Benchmark") << "GL LLVertexBuffer::getVertexStrider() returned false, "
 				   << "buff->getMappedData() is"
 				   << (buff->getMappedData()? " not" : "")
 				   << " NULL" << LL_ENDL;
@@ -1086,7 +1099,8 @@ F32 gpu_benchmark()
 	buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
 	glFinish();
 
-	for (S32 c = -1; c < samples; ++c)
+	F32 time_passed = 0; // seconds
+	for (S32 c = -1; c < samples && time_passed < time_limit; ++c)
 	{
 		LLTimer timer;
 		timer.start();
@@ -1103,6 +1117,7 @@ F32 gpu_benchmark()
 		glFinish();
 
 		F32 time = timer.getElapsedTimeF32();
+		time_passed += time;
 
 		if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
 		{ 
@@ -1117,12 +1132,12 @@ F32 gpu_benchmark()
 
 	F32 gbps = results[results.size()/2];
 
-	LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL;
-  
+	LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
+
 #if LL_DARWIN
     if (gbps > 512.f)
     { 
-        LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
+        LL_WARNS("Benchmark") << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
         //OSX is probably lying, discard result
         return -1.f;
     }
@@ -1131,11 +1146,11 @@ F32 gpu_benchmark()
 	F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
 	F32 seconds = ms/1000.f;
 
-	F64 samples_drawn = res*res*count*samples;
+	F64 samples_drawn = res*res*count*results.size();
 	F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
 	gbps = samples_sec*8;
 
-	LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
+	LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
 
 	return gbps;
 }
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 152d0eddcd19202664dcc718e4d5048a0a9232a3..088d052533566f605d5e2b75d8fcf2af87a3b1a0 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -2137,6 +2137,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
     static U32 lastGroupMemberRequestFrame = 0;
 
 	// Have we requested the information already this frame?
+    // Todo: make this per group, we can invite to one group and simultaneously be checking another one
     if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
 		return;
 	
@@ -2166,6 +2167,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 		return;
 	}
 
+    LLGroupMgrGroupData* group_datap = createGroupData(group_id); //make sure group exists
+    group_datap->mMemberRequestID.generate(); // mark as pending
+
     lastGroupMemberRequestFrame = gFrameCount;
 
     LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 940ef6eea13af48a80782c117585e3aed2235b8c..cf9735e38a0510ed0cb94ceb156f736501162ffa 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -258,6 +258,11 @@ friend class LLGroupMgr;
 	bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
 	bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
 
+	bool isMemberDataPending() { return mMemberRequestID.notNull(); }
+	bool isRoleDataPending() { return mRoleDataRequestID.notNull(); }
+	bool isRoleMemberDataPending() { return (mRoleMembersRequestID.notNull() || mPendingRoleMemberRequest); }
+	bool isGroupTitlePending() { return mTitlesRequestID.notNull(); }
+
 	bool isSingleMemberNotOwner();
 
 	F32 getAccessTime() const { return mAccessTime; }
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 074b0c9c1408cad01b0f8f4adc5a7a6c6b468cab..a50a66a8ce9fdec6de5dae30cd26b5b64dc6a001 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1399,13 +1399,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 			// Only should happen for broken links.
 			new_listener = new LLLinkItemBridge(inventory, root, uuid);
 			break;
-	    case LLAssetType::AT_MESH:
-			if(!(inv_type == LLInventoryType::IT_MESH))
-			{
-				LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
-			}
-			new_listener = new LLMeshBridge(inventory, root, uuid);
-			break;
 		case LLAssetType::AT_UNKNOWN:
 			new_listener = new LLUnknownItemBridge(inventory, root, uuid);
 			break;
@@ -2101,7 +2094,9 @@ BOOL LLItemBridge::isItemCopyable() const
 	LLViewerInventoryItem* item = getItem();
 	if (item)
 	{
-		// Can't copy worn objects. DEV-15183
+		// Can't copy worn objects.
+		// Worn objects are tied to their inworld conterparts
+		// Copy of modified worn object will return object with obsolete asset and inventory
 		if(get_is_item_worn(mUUID))
 		{
 			return FALSE;
@@ -6830,58 +6825,6 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	hide_context_entries(menu, items, disabled_items);
 }
 
-// +=================================================+
-// |        LLMeshBridge                             |
-// +=================================================+
-
-LLUIImagePtr LLMeshBridge::getIcon() const
-{
-	return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
-}
-
-void LLMeshBridge::openItem()
-{
-	LLViewerInventoryItem* item = getItem();
-	
-	if (item)
-	{
-		// open mesh
-	}
-}
-
-void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
-	LL_DEBUGS() << "LLMeshBridge::buildContextMenu()" << LL_ENDL;
-	std::vector<std::string> items;
-	std::vector<std::string> disabled_items;
-
-	if(isItemInTrash())
-	{
-		items.push_back(std::string("Purge Item"));
-		if (!isItemRemovable())
-		{
-			disabled_items.push_back(std::string("Purge Item"));
-		}
-
-		items.push_back(std::string("Restore Item"));
-	}
-    else if (isMarketplaceListingsFolder())
-    {
-		addMarketplaceContextMenuOptions(flags, items, disabled_items);
-		items.push_back(std::string("Properties"));
-		getClipboardEntries(false, items, disabled_items, flags);
-    }
-	else
-	{
-		items.push_back(std::string("Properties"));
-
-		getClipboardEntries(true, items, disabled_items, flags);
-	}
-
-	addLinkReplaceMenuOption(items, disabled_items);
-	hide_context_entries(menu, items, disabled_items);
-}
-
 
 // +=================================================+
 // |        LLLinkBridge                             |
@@ -7358,8 +7301,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
 	for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
 	{
 		LLViewerInventoryItem* item = gInventory.getItem(*it);
-		LLAssetType::EType asset_type = item->getType();
-		if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE))
+		if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
 		{
 			return false;
 		}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index ce06e8fffc81ece7d6909a42fde56d9acc4fae83..f4df566fa6d8e944abc9bb88417c95eb1faaf0a4 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -603,23 +603,6 @@ class LLLinkFolderBridge : public LLItemBridge
 	static std::string sPrefix;
 };
 
-
-class LLMeshBridge : public LLItemBridge
-{
-	friend class LLInvFVBridge;
-public:
-	virtual LLUIImagePtr getIcon() const;
-	virtual void openItem();
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-
-protected:
-	LLMeshBridge(LLInventoryPanel* inventory, 
-		     LLFolderView* root,
-		     const LLUUID& uuid) :
-                       LLItemBridge(inventory, root, uuid) {}
-};
-
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInvFVBridgeAction
 //
@@ -650,17 +633,6 @@ class LLInvFVBridgeAction
 	LLInventoryModel* mModel;
 };
 
-class LLMeshBridgeAction: public LLInvFVBridgeAction
-{
-	friend class LLInvFVBridgeAction;
-public:
-	virtual void	doIt() ;
-	virtual ~LLMeshBridgeAction(){}
-protected:
-	LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
-
-};
-
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Recent Inventory Panel related classes
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 9193613e9f2cd5cb5fbff8f6b4a33f96dbf84112..16385928b4d8e9e88d71289e5b48ef63d419956a 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -58,6 +58,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
 	mHoursAgo(p.hours_ago),
 	mDateSearchDirection(p.date_search_direction),
 	mShowFolderState(p.show_folder_state),
+	mFilterCreatorType(p.creator_type),
 	mPermissions(p.permissions),
 	mFilterTypes(p.types),
 	mFilterUUID(p.uuid),
@@ -78,8 +79,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 	mCurrentGeneration(0),
 	mFirstRequiredGeneration(0),
 	mFirstSuccessGeneration(0),
-	mSearchType(SEARCHTYPE_NAME),
-	mFilterCreatorType(FILTERCREATOR_ALL)
+	mSearchType(SEARCHTYPE_NAME)
 {
 	// copy mFilterOps into mDefaultFilterOps
 	markDefault();
@@ -489,7 +489,7 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
 {
 	if (!listener) return TRUE;
 	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
-	switch(mFilterCreatorType)
+	switch (mFilterOps.mFilterCreatorType)
 	{
 		case FILTERCREATOR_SELF:
 			if(is_folder) return FALSE;
@@ -601,9 +601,9 @@ void LLInventoryFilter::setSearchType(ESearchType type)
 
 void LLInventoryFilter::setFilterCreator(EFilterCreatorType type)
 {
-	if(mFilterCreatorType != type)
+	if (mFilterOps.mFilterCreatorType != type)
 	{
-		mFilterCreatorType = type;
+		mFilterOps.mFilterCreatorType = type;
 		setModified();
 	}
 }
@@ -1194,6 +1194,7 @@ void LLInventoryFilter::toParams(Params& params) const
 	params.filter_ops.hours_ago = getHoursAgo();
 	params.filter_ops.date_search_direction = getDateSearchDirection();
 	params.filter_ops.show_folder_state = getShowFolderState();
+	params.filter_ops.creator_type = getFilterCreatorType();
 	params.filter_ops.permissions = getFilterPermissions();
 	params.substring = getFilterSubString();
 	params.since_logoff = isSinceLogoff();
@@ -1216,6 +1217,7 @@ void LLInventoryFilter::fromParams(const Params& params)
 	setHoursAgo(params.filter_ops.hours_ago);
 	setDateSearchDirection(params.filter_ops.date_search_direction);
 	setShowFolderState(params.filter_ops.show_folder_state);
+	setFilterCreator(params.filter_ops.creator_type);
 	setFilterPermissions(params.filter_ops.permissions);
 	setFilterSubString(params.substring);
 	setDateRangeLastLogoff(params.since_logoff);
@@ -1278,6 +1280,11 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
 	return mFilterOps.mShowFolderState; 
 }
 
+LLInventoryFilter::EFilterCreatorType LLInventoryFilter::getFilterCreatorType() const
+{
+	return mFilterOps.mFilterCreatorType;
+}
+
 bool LLInventoryFilter::isTimedOut()
 {
 	return mFilterTime.hasExpired();
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 01754ed0232435f894144c06595703f60840f8cc..4a1fec8454893963b0d2c338bbf95894742607bf 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -126,6 +126,7 @@ class LLInventoryFilter : public LLFolderViewFilter
 			Optional<U32>				date_search_direction;
 			Optional<EFolderShow>		show_folder_state;
 			Optional<PermissionMask>	permissions;
+			Optional<EFilterCreatorType> creator_type;
 
 			Params()
 			:	types("filter_types", FILTERTYPE_OBJECT),
@@ -138,6 +139,7 @@ class LLInventoryFilter : public LLFolderViewFilter
 				hours_ago("hours_ago", 0),
 				date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER),
 				show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+				creator_type("creator_type", FILTERCREATOR_ALL),
 				permissions("permissions", PERM_NONE)
 			{}
 		};
@@ -156,8 +158,9 @@ class LLInventoryFilter : public LLFolderViewFilter
 		U32				mHoursAgo;
 		U32				mDateSearchDirection;
 
-		EFolderShow		mShowFolderState;
-		PermissionMask	mPermissions;
+		EFolderShow			mShowFolderState;
+		PermissionMask		mPermissions;
+		EFilterCreatorType	mFilterCreatorType;
 	};
 							
 	struct Params : public LLInitParam::Block<Params>
@@ -202,7 +205,6 @@ class LLInventoryFilter : public LLFolderViewFilter
 	void 				setSearchType(ESearchType type);
 	ESearchType			getSearchType() { return mSearchType; }
 	void 				setFilterCreator(EFilterCreatorType type);
-	EFilterCreatorType		getFilterCreator() { return mFilterCreatorType; }
 
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
@@ -243,8 +245,9 @@ class LLInventoryFilter : public LLFolderViewFilter
 	// +-------------------------------------------------------------------+
 	// + Presentation
 	// +-------------------------------------------------------------------+
-	void 				setShowFolderState( EFolderShow state);
-	EFolderShow 		getShowFolderState() const;
+	void 					setShowFolderState( EFolderShow state);
+	EFolderShow 			getShowFolderState() const;
+	EFilterCreatorType		getFilterCreatorType() const;
 
 	void 				setEmptyLookupMessage(const std::string& message);
 	std::string			getEmptyLookupMessage() const;
@@ -324,7 +327,6 @@ class LLInventoryFilter : public LLFolderViewFilter
 	std::string 			mEmptyLookupMessage;
 
 	ESearchType 			mSearchType;
-	EFilterCreatorType		mFilterCreatorType;
 };
 
 #endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b140c7c38e3050833695bb464f5403384100ea2e..c49d61df31128c59ea8bd066868057e6fdc5a560 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -888,14 +888,6 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 		return mask;
 	}
 
-	// We're hiding mesh types
-#if 0
-	if (item->getType() == LLAssetType::AT_MESH)
-	{
-		return mask;
-	}
-#endif
-
 	LLPointer<LLViewerInventoryItem> old_item = getItem(item->getUUID());
 	LLPointer<LLViewerInventoryItem> new_item;
 	if(old_item)
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index b0ee8e7fcb628e26cac3eef2e550f19ec52fb81c..51127928d1271e9125fb4bb2b829991cb0bc2b5c 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -65,11 +65,11 @@ class LLComInitialize
 
 S32 LLMachineID::init()
 {
-    memset(static_unique_id,0,sizeof(static_unique_id));
+    size_t len = sizeof(static_unique_id);
+    memset(static_unique_id, 0, len);
     S32 ret_code = 0;
 #if	LL_WINDOWS
 # pragma comment(lib, "wbemuuid.lib")
-        size_t len = sizeof(static_unique_id);
 
         // algorithm to detect BIOS serial number found at:
         // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
@@ -217,17 +217,27 @@ S32 LLMachineID::init()
 
             // Get the value of the Name property
             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
+            if (FAILED(hr))
+            {
+                LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL;
+                pclsObj->Release();
+                pclsObj = NULL;
+                continue;
+            }
             LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
+
             // use characters in the returned Serial Number to create a byte array of size len
             BSTR serialNumber ( vtProp.bstrVal);
+            unsigned int serial_size = SysStringLen(serialNumber);
             unsigned int j = 0;
-            while( vtProp.bstrVal[j] != 0)
+
+            while (j < serial_size && vtProp.bstrVal[j] != 0)
             {
                 for (unsigned int i = 0; i < len; i++)
                 {
-                    if (vtProp.bstrVal[j] == 0)
+                    if (j >= serial_size || vtProp.bstrVal[j] == 0)
                         break;
-                    
+
                     static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
                     j++;
                 }
@@ -254,16 +264,8 @@ S32 LLMachineID::init()
         ret_code = LLUUID::getNodeID(staticPtr);
 #endif
         has_static_unique_id = true;
-        return ret_code;
-}
-
 
-S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
-{
-    if (has_static_unique_id)
-    {
-        memcpy ( unique_id, &static_unique_id, len);
-        LL_INFOS_ONCE("AppInit") << "UniqueID: 0x";
+        LL_INFOS("AppInit") << "UniqueID: 0x";
         // Code between here and LL_ENDL is not executed unless the LL_DEBUGS
         // actually produces output
         for (size_t i = 0; i < len; ++i)
@@ -271,11 +273,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
             // Copy each char to unsigned int to hexify. Sending an unsigned
             // char to a std::ostream tries to represent it as a char, not
             // what we want here.
-            unsigned byte = unique_id[i];
+            unsigned byte = static_unique_id[i];
             LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
         }
         // Reset default output formatting to avoid nasty surprises!
         LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
+
+        return ret_code;
+}
+
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+    if (has_static_unique_id)
+    {
+        memcpy ( unique_id, &static_unique_id, len);
         return 1;
     }
     return 0;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 909936d9890cfe25be752537731202184ddab9d8..3209d23e430b7f127165c19fcee7444301871561 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -34,6 +34,7 @@
 #include "llcachename.h"
 #include "llfloater.h"
 #include "llfloaterreg.h"
+#include "llfloatersnapshot.h" // gSnapshotFloaterView
 #include "llinventory.h"
 #include "llscrolllistitem.h"
 #include "llscrolllistcell.h"
@@ -236,24 +237,30 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 
 				// Spawn at right side of cell
 				LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
-				LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
-
-				// Should we show a group or an avatar inspector?
-				bool is_group = hit_item->isGroup();
-				bool is_experience = hit_item->isExperience();
-
-				LLToolTip::Params params;
-				params.background_visible( false );
-				params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) );
-				params.delay_time(0.0f);		// spawn instantly on hover
-				params.image( icon );
-				params.message("");
-				params.padding(0);
-				params.pos(pos);
-				params.sticky_rect(sticky_rect);
-
-				LLToolTipMgr::getInstance()->show(params);
-				handled = TRUE;
+				S32 screenX = sticky_rect.mRight - info_icon_size;
+				S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;
+				LLCoordGL pos(screenX, screenY);
+
+				LLFloater* snapshot_floatr = gSnapshotFloaterView->getFrontmostClosableFloater();
+				if (!snapshot_floatr || !snapshot_floatr->getRect().pointInRect(screenX + icon->getWidth(), screenY))
+				{
+					// Should we show a group or an avatar inspector?
+					bool is_group = hit_item->isGroup();
+					bool is_experience = hit_item->isExperience();
+
+					LLToolTip::Params params;
+					params.background_visible(false);
+					params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience));
+					params.delay_time(0.0f);		// spawn instantly on hover
+					params.image(icon);
+					params.message("");
+					params.padding(0);
+					params.pos(pos);
+					params.sticky_rect(sticky_rect);
+
+					LLToolTipMgr::getInstance()->show(params);
+					handled = TRUE;
+				}
 			}
 		}
 	}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index fef0631fa6c3b8de4860be354b0a24dfb9cd645b..ba831ab2ed3cf9995e6222a1ed88bb202cf45cf2 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -35,7 +35,6 @@
 #include "llnotificationmanager.h"
 #include "llnotifications.h"
 #include "llscriptfloater.h"
-#include "llfacebookconnect.h"
 #include "llavatarname.h"
 #include "llavatarnamecache.h"
 
diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp
index a7f2dbafa2d56a34ec9221548e225b0be429e727..80aeee6da1687b22a4ea6e3caac701919828b07b 100644
--- a/indra/newview/llpanelexperiencepicker.cpp
+++ b/indra/newview/llpanelexperiencepicker.cpp
@@ -89,7 +89,7 @@ BOOL LLPanelExperiencePicker::postBuild()
 	childSetAction(BTN_PROFILE, boost::bind(&LLPanelExperiencePicker::onBtnProfile, this));
 	getChildView(BTN_PROFILE)->setEnabled(FALSE);
 
-	getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(2);
+	getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(gSavedPerAccountSettings.getU32("ExperienceSearchMaturity"));
 	getChild<LLComboBox>(TEXT_MATURITY)->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onMaturity, this));
 	getChild<LLUICtrl>(TEXT_EDIT)->setFocus(TRUE);
 
@@ -381,6 +381,7 @@ void LLPanelExperiencePicker::filterContent()
 
 void LLPanelExperiencePicker::onMaturity()
 {
+	gSavedPerAccountSettings.setU32("ExperienceSearchMaturity", getChild<LLComboBox>(TEXT_MATURITY)->getCurrentIndex());
 	if(mResponse.has("experience_keys") && mResponse["experience_keys"].beginArray() != mResponse["experience_keys"].endArray())
 	{
 		filterContent();
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 82ea8377de684a9b91177d26c0d029e34b31177a..d6b66ee6225a7a961109a46f4bf688aafa326e39 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -606,11 +606,30 @@ void LLPanelGroupInvite::updateLists()
 	{
 		if (!mPendingUpdate) 
 		{
+			// Note: this will partially fail if some requests are already in progress
 			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
 			LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
 			LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
 		}
+        else if (gdatap)
+        {
+            // restart requests that were interrupted/dropped/failed to start
+            if (!gdatap->isRoleDataPending() && !gdatap->isRoleDataComplete())
+            {
+                LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
+            }
+            if (!gdatap->isRoleMemberDataPending() && !gdatap->isRoleMemberDataComplete())
+            {
+                LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
+            }
+            // sendCapGroupMembersRequest has a per frame send limitation that could have
+            // interrupted previous request
+            if (!gdatap->isMemberDataPending() && !gdatap->isMemberDataComplete())
+            {
+                LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
+            }
+        }
 		mPendingUpdate = TRUE;
 	} 
 	else
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 52a13304df3418adb06679039e2d23efc6960665..0efb234015b52252f745b9798eefdd92ac554b3b 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1962,6 +1962,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
 	mRoleDescription(NULL),
 	mMemberVisibleCheck(NULL),
 	mDeleteRoleButton(NULL),
+	mCopyRoleButton(NULL),
 	mCreateRoleButton(NULL),
 	mFirstOpen(TRUE),
 	mHasRoleChange(FALSE)
@@ -2012,6 +2013,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
 		mCreateRoleButton->setClickedCallback(onCreateRole, this);
 		mCreateRoleButton->setEnabled(FALSE);
 	}
+
+	mCopyRoleButton = 
+		parent->getChild<LLButton>("role_copy", recurse);
+	if ( mCopyRoleButton )
+	{
+		mCopyRoleButton->setClickedCallback(onCopyRole, this);
+		mCopyRoleButton->setEnabled(FALSE);
+	}
 	
 	mDeleteRoleButton =  
 		parent->getChild<LLButton>("role_delete", recurse);
@@ -2226,6 +2235,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
 			mRoleTitle->clear();
 			setFooterEnabled(FALSE);
 			mDeleteRoleButton->setEnabled(FALSE);
+			mCopyRoleButton->setEnabled(FALSE);
 		}
 	}
 	
@@ -2336,6 +2346,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
 	mSelectedRole = item->getUUID();
 	buildMembersList();
 
+	mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE));
 	can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID,
 													  GP_ROLE_DELETE);
 	mDeleteRoleButton->setEnabled(can_delete);
@@ -2661,6 +2672,57 @@ void LLPanelGroupRolesSubTab::handleCreateRole()
 	notifyObservers();
 }
 
+// static 
+void LLPanelGroupRolesSubTab::onCopyRole(void* user_data)
+{
+	LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
+	if (!self) return;
+
+	self->handleCopyRole();
+}
+
+void LLPanelGroupRolesSubTab::handleCopyRole()
+{
+	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
+
+	if (!gdatap) return;
+
+	LLScrollListItem* role_item = mRolesList->getFirstSelected();
+	if (!role_item || role_item->getUUID().isNull())
+	{
+		return;
+	}
+
+	LLRoleData rd;
+	if (!gdatap->getRoleData(role_item->getUUID(), rd))
+	{
+		return;
+	}
+
+	LLUUID new_role_id;
+	new_role_id.generate();
+	rd.mRoleName += "(Copy)";
+	gdatap->createRole(new_role_id,rd);
+
+	mRolesList->deselectAllItems(TRUE);
+	LLSD row;
+	row["id"] = new_role_id;
+	row["columns"][0]["column"] = "name";
+	row["columns"][0]["value"] = rd.mRoleName;
+	mRolesList->addElement(row, ADD_BOTTOM, this);
+	mRolesList->selectByID(new_role_id);
+
+	// put focus on name field and select its contents
+	if(mRoleName)
+	{
+		mRoleName->setFocus(TRUE);
+		mRoleName->onTabInto();
+		gFocusMgr.triggerFocusFlash();
+	}
+
+	notifyObservers();
+}
+
 // static 
 void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data)
 {
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index aafbd242cbf98fec37e37c39ca8cee8dd7ba986f..459b77703f3729bde9b27e2edc77eed8844b102a 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -269,6 +269,9 @@ class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
 	static void onCreateRole(void*);
 	void handleCreateRole();
 
+	static void onCopyRole(void*);
+	void handleCopyRole();
+
 	static void onDeleteRole(void*);
 	void handleDeleteRole();
 
@@ -296,6 +299,7 @@ class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
 	LLCheckBoxCtrl* mMemberVisibleCheck;
 	LLButton*       mDeleteRoleButton;
 	LLButton*       mCreateRoleButton;
+	LLButton*       mCopyRoleButton;
 
 	LLUUID	mSelectedRole;
 	BOOL	mHasRoleChange;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 142dea83e2d2b9cf45760151223a2eec1057653f..e253557797de8c149132fbffcde1d8a1fce24e05 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -178,7 +178,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	mPasswordModified = FALSE;
 
-	LLPanelLogin::sInstance = this;
+	sInstance = this;
 
 	LLView* login_holder = gViewerWindow->getLoginPanelHolder();
 	if (login_holder)
@@ -234,29 +234,44 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), 
 							 current_grid,
 							 ADD_TOP);	
-	server_choice_combo->selectFirstItem();		
+	server_choice_combo->selectFirstItem();
 
 	LLSLURL start_slurl(LLStartUp::getStartSLURL());
+	// The StartSLURL might have been set either by an explicit command-line
+	// argument (CmdLineLoginLocation) or by default.
+	// current_grid might have been set either by an explicit command-line
+	// argument (CmdLineGridChoice) or by default.
+	// If the grid specified by StartSLURL is the same as current_grid, the
+	// distinction is moot.
+	// If we have an explicit command-line SLURL, use that.
+	// If we DON'T have an explicit command-line SLURL but we DO have an
+	// explicit command-line grid, which is different from the default SLURL's
+	// -- do NOT override the explicit command-line grid with the grid from
+	// the default SLURL!
+	bool force_grid{ start_slurl.getGrid() != current_grid &&
+					 gSavedSettings.getString("CmdLineLoginLocation").empty() &&
+				   ! gSavedSettings.getString("CmdLineGridChoice").empty() };
 	if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ? 
 	{
 		// no, so get the preference setting
 		std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
 		LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL;
 		LLSLURL defaultStart(defaultStartLocation);
-		if ( defaultStart.isSpatial() )
+		if ( defaultStart.isSpatial() && ! force_grid )
 		{
 			LLStartUp::setStartSLURL(defaultStart);
 		}
 		else
 		{
-			LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL;
+			LL_INFOS("AppInit") << (force_grid? "--grid specified" : "no valid LoginLocation")
+								<< ", using home" << LL_ENDL;
 			LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME);
 			LLStartUp::setStartSLURL(homeStart);
 		}
 	}
-	else
+	else if (! force_grid)
 	{
-		LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
+		onUpdateStartSLURL(start_slurl); // updates grid if needed
 	}
 	
 	childSetAction("connect_btn", onClickConnect, this);
@@ -380,7 +395,7 @@ void LLPanelLogin::setFocus(BOOL b)
 	{
 		if(b)
 		{
-			LLPanelLogin::giveFocus();
+			giveFocus();
 		}
 		else
 		{
@@ -748,7 +763,10 @@ void LLPanelLogin::closePanel()
 {
 	if (sInstance)
 	{
-		LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
+		if (LLPanelLogin::sInstance->getParent())
+		{
+			LLPanelLogin::sInstance->getParent()->removeChild(LLPanelLogin::sInstance);
+		}
 
 		delete sInstance;
 		sInstance = NULL;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index db9d61c637bc13babd0ad935fd5a5545023dd6f6..f63e604927b75b9e9604b2b0ada2d934c5d0763a 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -885,7 +885,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
 	U32 hours = mFilter->getHoursAgo();
 	U32 date_search_direction = mFilter->getDateSearchDirection();
 
-	LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreator();
+	LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType();
 	bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF));
 	bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS));
 
@@ -898,7 +898,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
 	getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
 	getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
 	getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
-	getChild<LLUICtrl>("check_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH));
 	getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
 	getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
 	getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@@ -954,12 +953,6 @@ void LLFloaterInventoryFinder::draw()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (!getChild<LLUICtrl>("check_mesh")->getValue())
-	{
-		filter &= ~(0x1 << LLInventoryType::IT_MESH);
-		filtered_by_all_types = FALSE;
-	}
-
 	if (!getChild<LLUICtrl>("check_notecard")->getValue())
 	{
 		filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@@ -1108,7 +1101,6 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
 	self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
 	self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
 	self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
-	self->getChild<LLUICtrl>("check_mesh")->setValue(TRUE);
 	self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
 	self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
 	self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
@@ -1128,7 +1120,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
 	self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
 	self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
 	self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
-	self->getChild<LLUICtrl>("check_mesh")->setValue(FALSE);
 	self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
 	self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
 	self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index cd1875e995898164d16d6f0b5048261f1c5a7c88..6702dae4d6cb73d0e6e0b6d324cce741f0879079 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1121,92 +1121,6 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const
 	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );
 }
 
-///----------------------------------------------------------------------------
-/// Class LLTaskMeshBridge
-///----------------------------------------------------------------------------
-
-class LLTaskMeshBridge : public LLTaskInvFVBridge
-{
-public:
-	LLTaskMeshBridge(
-		LLPanelObjectInventory* panel,
-		const LLUUID& uuid,
-		const std::string& name);
-
-	virtual LLUIImagePtr getIcon() const;
-	virtual void openItem();
-	virtual void performAction(LLInventoryModel* model, std::string action);
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-};
-
-LLTaskMeshBridge::LLTaskMeshBridge(
-	LLPanelObjectInventory* panel,
-	const LLUUID& uuid,
-	const std::string& name) :
-	LLTaskInvFVBridge(panel, uuid, name)
-{
-}
-
-LLUIImagePtr LLTaskMeshBridge::getIcon() const
-{
-	return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
-}
-
-void LLTaskMeshBridge::openItem()
-{
-	// open mesh
-}
-
-
-// virtual
-void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action)
-{
-	if (action == "mesh action")
-	{
-		LLInventoryItem* item = findItem();
-		if(item)
-		{
-			// do action
-		}
-	}
-	LLTaskInvFVBridge::performAction(model, action);
-}
-
-void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
-	LLInventoryItem* item = findItem();
-	std::vector<std::string> items;
-	std::vector<std::string> disabled_items;
-	if(!item)
-	{
-		hide_context_entries(menu, items, disabled_items);
-		return;
-	}
-
-	items.push_back(std::string("Task Open")); 
-	if (!isItemCopyable())
-	{
-		disabled_items.push_back(std::string("Task Open"));
-	}
-
-	items.push_back(std::string("Task Properties"));
-	if ((flags & FIRST_SELECTED_ITEM) == 0)
-	{
-		disabled_items.push_back(std::string("Task Properties"));
-	}
-	if(isItemRenameable())
-	{
-		items.push_back(std::string("Task Rename"));
-	}
-	if(isItemRemovable())
-	{
-		items.push_back(std::string("Task Remove"));
-	}
-
-
-	hide_context_entries(menu, items, disabled_items);
-}
-
 ///----------------------------------------------------------------------------
 /// LLTaskInvFVBridge impl
 //----------------------------------------------------------------------------
@@ -1288,11 +1202,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
 						 object_id,
 						 object_name);
 		break;
-	case LLAssetType::AT_MESH:
-		new_bridge = new LLTaskMeshBridge(panel,
-										  object_id,
-										  object_name);
-		break;
 	default:
 		LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
 				<< (S32)type << LL_ENDL;
@@ -1498,7 +1407,14 @@ void LLPanelObjectInventory::updateInventory()
 			mIsInventoryEmpty = TRUE;
 		}
 
-		mHaveInventory = TRUE;
+		mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty();
+		if (objectp->isInventoryDirty())
+		{
+			// Inventory is dirty, yet we received inventoryChanged() callback.
+			// User changed something during ongoing request.
+			// Rerequest. It will clear dirty flag and won't create dupplicate requests.
+			objectp->requestInventory();
+		}
 	}
 	else
 	{
@@ -1768,7 +1684,7 @@ void LLPanelObjectInventory::deleteAllChildren()
 
 BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
 {
-	if (mFolders && mHaveInventory)
+	if (mFolders)
 	{
 		LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
 		if (!folderp)
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index d700c8f4cfb73bf96edce26ec1c45912a1c246ab..7b9ecfb8f31d6914fc9c4b77f8fbe3f7cf138131 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -106,9 +106,9 @@ class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
 	
 	LLUUID mTaskUUID;
 	LLUUID mAttachmentUUID;
-	BOOL mHaveInventory;
-	BOOL mIsInventoryEmpty;
-	BOOL mInventoryNeedsUpdate;
+	BOOL mHaveInventory; // 'Loading' label and used for initial request
+	BOOL mIsInventoryEmpty; // 'Empty' label
+	BOOL mInventoryNeedsUpdate; // for idle, set on changed callback
 	LLFolderViewModelInventory	mInventoryViewModel;	
 };
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 617ca052812d610c5f618ebf6a492a5a5127c18c..be174475e18e4df9f60522763e46a1e0882b0e03 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -54,7 +54,6 @@
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llcallbacklist.h"
 #include "llerror.h"
-#include "llfacebookconnect.h"
 #include "llfloateravatarpicker.h"
 #include "llfriendcard.h"
 #include "llgroupactions.h"
@@ -537,7 +536,6 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
 
 LLPanelPeople::LLPanelPeople()
 	:	LLPanel(),
-		mTryToConnectToFacebook(true),
 		mTabContainer(NULL),
 		mOnlineFriendList(NULL),
 		mAllFriendList(NULL),
@@ -645,11 +643,9 @@ BOOL LLPanelPeople::postBuild()
 	// updater is active only if panel is visible to user.
 	friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
     friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
-	friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::updateFacebookList, this, _2));
 
 	mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
 	mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
-	mSuggestedFriends = friends_tab->getChild<LLAvatarList>("suggested_friends");
 	mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
 	mOnlineFriendList->setShowIcons("FriendsListShowIcons");
 	mOnlineFriendList->showPermissions("FriendsListShowPermissions");
@@ -685,7 +681,6 @@ BOOL LLPanelPeople::postBuild()
 	mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
 	mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
 	mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
-	mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
 
 	setSortOrder(mRecentList,		(ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"),	false);
 	setSortOrder(mAllFriendList,	(ESortOrder)gSavedSettings.getU32("FriendsSortOrder"),		false);
@@ -764,7 +759,7 @@ void LLPanelPeople::updateFriendListHelpText()
 
 	// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
 	// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
-	bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches() || mSuggestedFriends->filterHasMatches();
+	bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches();
 	no_friends_text->setVisible(!any_friend_exists);
 	if (no_friends_text->getVisible())
 	{
@@ -831,40 +826,9 @@ void LLPanelPeople::updateFriendList()
 	mAllFriendList->setDirty(true, !mAllFriendList->filterHasMatches());
 	//update trash and other buttons according to a selected item
 	updateButtons();
-	updateSuggestedFriendList();
 	showFriendsAccordionsIfNeeded();
 }
 
-bool LLPanelPeople::updateSuggestedFriendList()
-{
-	const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
-	uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
-	suggested_friends.clear();
-
-	//Add suggested friends
-	LLSD friends = LLFacebookConnect::instance().getContent();
-	for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
-	{
-		LLUUID agent_id = (*i).asUUID();
-		bool second_life_buddy = agent_id.notNull() ? av_tracker.isBuddy(agent_id) : false;
-
-		if(!second_life_buddy)
-		{
-			//FB+SL but not SL friend
-			if (agent_id.notNull())
-			{
-				suggested_friends.push_back(agent_id);
-			}
-		}
-	}
-
-	//Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
-	mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
-	showFriendsAccordionsIfNeeded();
-
-	return false;
-}
-
 void LLPanelPeople::updateNearbyList()
 {
 	if (!mNearbyList)
@@ -888,51 +852,6 @@ void LLPanelPeople::updateRecentList()
 	mRecentList->setDirty();
 }
 
-bool LLPanelPeople::onConnectedToFacebook(const LLSD& data)
-{
-	LLSD::Integer connection_state = data.get("enum").asInteger();
-
-	if (connection_state == LLFacebookConnect::FB_CONNECTED)
-	{
-		LLFacebookConnect::instance().loadFacebookFriends();
-	}
-	else if(connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
-	{
-		updateSuggestedFriendList();
-	};
-
-	return false;
-}
-
-void LLPanelPeople::updateFacebookList(bool visible)
-{
-	if (visible)
-	{
-		LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); // just in case it is already listening
-		LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLPanelPeople", boost::bind(&LLPanelPeople::updateSuggestedFriendList, this));
-
-		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); // just in case it is already listening
-		LLEventPumps::instance().obtain("FacebookConnectState").listen("LLPanelPeople", boost::bind(&LLPanelPeople::onConnectedToFacebook, this, _1));
-
-		if (LLFacebookConnect::instance().isConnected())
-		{
-			LLFacebookConnect::instance().loadFacebookFriends();
-		}
-		else if(mTryToConnectToFacebook)
-		{
-			LLFacebookConnect::instance().checkConnectionToFacebook();
-			mTryToConnectToFacebook = false;
-		}
-    
-		updateSuggestedFriendList();
-	}
-	else
-	{
-		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople");
-		LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople");
-	}
-}
-
 void LLPanelPeople::updateButtons()
 {
 	std::string cur_tab		= getActiveTabName();
@@ -1151,11 +1070,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
 
 		mOnlineFriendList->setNameFilter(filter);
 		mAllFriendList->setNameFilter(filter);
-		mSuggestedFriends->setNameFilter(filter);
 
         setAccordionCollapsedByUser("tab_online", false);
         setAccordionCollapsedByUser("tab_all", false);
-		setAccordionCollapsedByUser("tab_suggested_friends", false);
         showFriendsAccordionsIfNeeded();
 
 		// restore accordion tabs state _after_ all manipulations
@@ -1600,7 +1517,6 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()
 		// Expand and show accordions if needed, else - hide them
 		showAccordion("tab_online", mOnlineFriendList->filterHasMatches());
 		showAccordion("tab_all", mAllFriendList->filterHasMatches());
-		showAccordion("tab_suggested_friends", mSuggestedFriends->filterHasMatches());
 
 		// Rearrange accordions
 		LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index c72c4fc08a2375fcc339e736509bad6f9d57b540..14205cebe2fd831f3daafcd098bf8fe431bf7622 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -57,8 +57,6 @@ class LLPanelPeople
 	// when voice is available
 	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
 
-    bool mTryToConnectToFacebook;
-
 	// internals
 	class Updater;
 
@@ -80,10 +78,8 @@ class LLPanelPeople
 	// methods indirectly called by the updaters
 	void					updateFriendListHelpText();
 	void					updateFriendList();
-	bool					updateSuggestedFriendList();
 	void					updateNearbyList();
 	void					updateRecentList();
-	void					updateFacebookList(bool visible);
 
 	bool					isItemsFreeOfFriends(const uuid_vec_t& uuids);
 
@@ -131,8 +127,6 @@ class LLPanelPeople
 
 	void					onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param);
 
-	bool					onConnectedToFacebook(const LLSD& data);
-
 	void					setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
 	void					setAccordionCollapsedByUser(const std::string& name, bool collapsed);
 	bool					isAccordionCollapsedByUser(LLUICtrl* acc_tab);
@@ -141,7 +135,6 @@ class LLPanelPeople
 	LLTabContainer*			mTabContainer;
 	LLAvatarList*			mOnlineFriendList;
 	LLAvatarList*			mAllFriendList;
-	LLAvatarList*			mSuggestedFriends;
 	LLAvatarList*			mNearbyList;
 	LLAvatarList*			mRecentList;
 	LLGroupList*			mGroupList;
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 65769ff526490982f8e6b07eb6d22f49ba67ae59..42cecc9986c7c17f3cc4daef16bfbbd7aa90d72f 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -52,7 +52,6 @@ namespace LLPanelPeopleMenus
 
 PeopleContextMenu gPeopleContextMenu;
 NearbyPeopleContextMenu gNearbyPeopleContextMenu;
-SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
 
 //== PeopleContextMenu ===============================================================
 
@@ -413,36 +412,4 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
     hide_context_entries(menu, items, disabled_items);
 }
 
-//== SuggestedFriendsContextMenu ===============================================================
-
-LLContextMenu* SuggestedFriendsContextMenu::createMenu()
-{
-	// set up the callbacks for all of the avatar menu items
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	LLContextMenu* menu;
-
-	// Set up for one person selected menu
-	const LLUUID& id = mUUIDs.front();
-	registrar.add("Avatar.Profile",			boost::bind(&LLAvatarActions::showProfile,				id));
-	registrar.add("Avatar.AddFriend",		boost::bind(&LLAvatarActions::requestFriendshipDialog,	id));
-
-	// create the context menu from the XUI
-	menu = createFromFile("menu_people_nearby.xml");
-	buildContextMenu(*menu, 0x0);
-
-	return menu;
-}
-
-void SuggestedFriendsContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
-{ 
-	menuentry_vec_t items;
-	menuentry_vec_t disabled_items;
-
-	items.push_back(std::string("view_profile"));
-	items.push_back(std::string("add_friend"));
-
-	hide_context_entries(menu, items, disabled_items);
-}
-
 } // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index 5ed20e00640c0d0ecac0ce68dae818e6f161f066..3bc1f8caf7da486cb889edcc82da13b673ea7919 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -62,21 +62,8 @@ class NearbyPeopleContextMenu : public PeopleContextMenu
 	/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
 };
 
-/**
- * Menu used in the suggested friends list.
- */
-class SuggestedFriendsContextMenu : public PeopleContextMenu
-{
-public:
-	/*virtual*/ LLContextMenu * createMenu();
-
-protected:
-	/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
-};
-
 extern PeopleContextMenu gPeopleContextMenu;
 extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
-extern SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
 
 } // namespace LLPanelPeopleMenus
 
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 610b3a6396068610a98a1d81737dd3249dbcd7bd..104316e2534bcf5d08e67534843f5bfaa1a800b4 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -563,11 +563,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 			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));
+		mSalesPriceText->setText(llformat("%s%d ", getString("price_text").c_str(), parcel->getSalePrice()));
+		mAreaText->setText(llformat("%d %s", area, getString("area_text").c_str()));
 		mTrafficText->setText(llformat("%.0f", dwell));
 
 		// Can't have more than region max tasks, regardless of parcel
@@ -575,10 +572,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		S32 primitives = llmin(ll_round(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));
+		mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, getString("available").c_str(), parcel->getPrimCount(), getString("allocated").c_str()));
 
 		if (parcel->getAllowOtherScripts())
 		{
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 95c14e4226c9eef40b6093a70fd1895bbca43669..23747a8efdebb025ada0d9a20c7de5ea8962cd4a 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -32,7 +32,6 @@
 
 #include "llfloatersnapshot.h" // FIXME: create a snapshot model
 #include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
 #include "llfloaterflickr.h"
 #include "llfloatertwitter.h"
 
@@ -59,7 +58,6 @@ class LLPanelSnapshotOptions
 	void onSaveToEmail();
 	void onSaveToInventory();
 	void onSaveToComputer();
-	void onSendToFacebook();
 	void onSendToTwitter();
 	void onSendToFlickr();
 
@@ -74,7 +72,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
 	mCommitCallbackRegistrar.add("Snapshot.SaveToEmail",		boost::bind(&LLPanelSnapshotOptions::onSaveToEmail,		this));
 	mCommitCallbackRegistrar.add("Snapshot.SaveToInventory",	boost::bind(&LLPanelSnapshotOptions::onSaveToInventory,	this));
 	mCommitCallbackRegistrar.add("Snapshot.SaveToComputer",		boost::bind(&LLPanelSnapshotOptions::onSaveToComputer,	this));
-	mCommitCallbackRegistrar.add("Snapshot.SendToFacebook",		boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this));
 	mCommitCallbackRegistrar.add("Snapshot.SendToTwitter",		boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
 	mCommitCallbackRegistrar.add("Snapshot.SendToFlickr",		boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
 	LLGlobalEconomy::getInstance()->addObserver(this);
@@ -138,18 +135,6 @@ void LLPanelSnapshotOptions::onSaveToComputer()
 	openPanel("panel_snapshot_local");
 }
 
-void LLPanelSnapshotOptions::onSendToFacebook()
-{
-	LLFloaterReg::hideInstance("snapshot");
-
-	LLFloaterFacebook* facebook_floater = dynamic_cast<LLFloaterFacebook*>(LLFloaterReg::getInstance("facebook"));
-	if (facebook_floater)
-	{
-		facebook_floater->showPhotoPanel();
-	}
-	LLFloaterReg::showInstance("facebook");
-}
-
 void LLPanelSnapshotOptions::onSendToTwitter()
 {
 	LLFloaterReg::hideInstance("snapshot");
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index d4a8bbdf453242a8acfa3db06b16ddb38c6e0698..1533a2746952765787b5130195ce7b5467f7f691 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -32,6 +32,7 @@
 
 #include "llagent.h"
 #include "lldraghandle.h"
+#include "llexternaleditor.h"
 #include "llviewerwindow.h"
 #include "llbutton.h"
 #include "llfloaterreg.h"
@@ -43,6 +44,7 @@
 #include "roles_constants.h"
 #include "llscrollbar.h"
 #include "llselectmgr.h"
+#include "lltrans.h"
 #include "llviewertexteditor.h"
 #include "llvfile.h"
 #include "llviewerinventory.h"
@@ -63,7 +65,8 @@
 
 // Default constructor
 LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, 
-	: LLPreview( key )
+	: LLPreview( key ),
+	mLiveFile(NULL)
 {
 	const LLInventoryItem *item = getItem();
 	if (item)
@@ -74,13 +77,14 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
 
 LLPreviewNotecard::~LLPreviewNotecard()
 {
+	delete mLiveFile;
 }
 
 BOOL LLPreviewNotecard::postBuild()
 {
-	LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
-	ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
-	ed->makePristine();
+	mEditor = getChild<LLViewerTextEditor>("Notecard Editor");
+	mEditor->setNotecardInfo(mItemUUID, mObjectID, getKey());
+	mEditor->makePristine();
 
 	childSetAction("Save", onClickSave, this);
 	getChildView("lock")->setVisible( FALSE);	
@@ -88,6 +92,8 @@ BOOL LLPreviewNotecard::postBuild()
 	childSetAction("Delete", onClickDelete, this);
 	getChildView("Delete")->setEnabled(false);
 
+	childSetAction("Edit", onClickEdit, this);
+
 	const LLInventoryItem* item = getItem();
 
 	childSetCommitCallback("desc", LLPreview::onText, this);
@@ -408,6 +414,16 @@ void LLPreviewNotecard::onClickDelete(void* user_data)
 	}
 }
 
+// static
+void LLPreviewNotecard::onClickEdit(void* user_data)
+{
+	LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
+	if (preview)
+	{
+		preview->openInExternalEditor();
+	}
+}
+
 struct LLSaveNotecardInfo
 {
 	LLPreviewNotecard* mSelf;
@@ -468,7 +484,7 @@ void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUI
     }
 }
 
-bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
+bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
 {
 	LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
 
@@ -487,7 +503,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
 		}
 
 		editor->makePristine();
-
+		if (sync)
+		{
+			syncExternal();
+		}
 		const LLInventoryItem* item = getItem();
 		// save it out to database
         if (item)
@@ -566,6 +585,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
 	return true;
 }
 
+void LLPreviewNotecard::syncExternal()
+{
+	// Sync with external editor.
+	std::string tmp_file = getTmpFileName();
+	llstat s;
+	if (LLFile::stat(tmp_file, &s) == 0) // file exists
+	{
+		if (mLiveFile) mLiveFile->ignoreNextUpdate();
+		writeToFile(tmp_file);
+	}
+}
+
 void LLPreviewNotecard::deleteNotecard()
 {
 	LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2));
@@ -714,4 +745,128 @@ bool LLPreviewNotecard::handleConfirmDeleteDialog(const LLSD& notification, cons
 	return false;
 }
 
+void LLPreviewNotecard::openInExternalEditor()
+{
+    delete mLiveFile; // deletes file
+
+    // Save the notecard to a temporary file.
+    std::string filename = getTmpFileName();
+    writeToFile(filename);
+
+    // Start watching file changes.
+    mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1));
+    mLiveFile->addToEventTimer();
+
+    // Open it in external editor.
+    {
+        LLExternalEditor ed;
+        LLExternalEditor::EErrorCode status;
+        std::string msg;
+
+        status = ed.setCommand("LL_SCRIPT_EDITOR");
+        if (status != LLExternalEditor::EC_SUCCESS)
+        {
+            if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+            {
+                msg = LLTrans::getString("ExternalEditorNotSet");
+            }
+            else
+            {
+                msg = LLExternalEditor::getErrorMessage(status);
+            }
+
+            LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+            return;
+        }
+
+        status = ed.run(filename);
+        if (status != LLExternalEditor::EC_SUCCESS)
+        {
+            msg = LLExternalEditor::getErrorMessage(status);
+            LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+        }
+    }
+}
+
+bool LLPreviewNotecard::onExternalChange(const std::string& filename)
+{
+    if (!loadNotecardText(filename))
+    {
+        return false;
+    }
+
+    // Disable sync to avoid recursive load->save->load calls.
+    saveIfNeeded(NULL, false);
+    return true;
+}
+
+bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
+{
+    if (filename.empty())
+    {
+        LL_WARNS() << "Empty file name" << LL_ENDL;
+        return false;
+    }
+
+    LLFILE* file = LLFile::fopen(filename, "rb");		/*Flawfinder: ignore*/
+    if (!file)
+    {
+        LL_WARNS() << "Error opening " << filename << LL_ENDL;
+        return false;
+    }
+
+    // read in the whole file
+    fseek(file, 0L, SEEK_END);
+    size_t file_length = (size_t)ftell(file);
+    fseek(file, 0L, SEEK_SET);
+    char* buffer = new char[file_length + 1];
+    size_t nread = fread(buffer, 1, file_length, file);
+    if (nread < file_length)
+    {
+        LL_WARNS() << "Short read" << LL_ENDL;
+    }
+    buffer[nread] = '\0';
+    fclose(file);
+
+    mEditor->setText(LLStringExplicit(buffer));
+    delete[] buffer;
+
+    return true;
+}
+
+bool LLPreviewNotecard::writeToFile(const std::string& filename)
+{
+    LLFILE* fp = LLFile::fopen(filename, "wb");
+    if (!fp)
+    {
+        LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
+        return false;
+    }
+
+    std::string utf8text = mEditor->getText();
+
+    if (utf8text.size() == 0)
+    {
+        utf8text = " ";
+    }
+
+    fputs(utf8text.c_str(), fp);
+    fclose(fp);
+    return true;
+}
+
+
+std::string LLPreviewNotecard::getTmpFileName()
+{
+    std::string notecard_id = mObjectID.asString() + "_" + mItemUUID.asString();
+
+    // Use MD5 sum to make the file name shorter and not exceed maximum path length.
+    char notecard_id_hash_str[33];			   /* Flawfinder: ignore */
+    LLMD5 notecard_id_hash((const U8 *)notecard_id.c_str());
+    notecard_id_hash.hex_digest(notecard_id_hash_str);
+
+    return std::string(LLFile::tmpdir()) + "sl_notecard_" + notecard_id_hash_str + ".txt";
+}
+
+
 // EOF
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 46a6d0ef501e0bc2b49d8de438106904bad6a903..d9c14815c177abcca0e2bd0a5c65b91af090c0d4 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -29,6 +29,7 @@
 
 #include "llpreview.h"
 #include "llassetstorage.h"
+#include "llpreviewscript.h"
 #include "lliconctrl.h"
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -47,18 +48,18 @@ class LLPreviewNotecard : public LLPreview
 	virtual ~LLPreviewNotecard();
 	
 	bool saveItem();
-	void setObjectID(const LLUUID& object_id);
+	void setObjectID(const LLUUID& object_id) override;
 
 	// llview
-	virtual void draw();
-	virtual BOOL handleKeyHere(KEY key, MASK mask);
-	virtual void setEnabled( BOOL enabled );
+	void draw() override;
+	BOOL handleKeyHere(KEY key, MASK mask) override;
+	void setEnabled( BOOL enabled ) override;
 
 	// llfloater
-	virtual BOOL canClose();
+	BOOL canClose() override;
 
 	// llpanel
-	virtual BOOL postBuild();
+	BOOL postBuild() override;
 
 	// reach into the text editor, and grab the drag item
 	const LLInventoryItem* getDragItem();
@@ -72,11 +73,13 @@ class LLPreviewNotecard : public LLPreview
 	// asset system. :(
 	void refreshFromInventory(const LLUUID& item_id = LLUUID::null);
 
+	void syncExternal();
+
 protected:
 
-	void updateTitleButtons();
-	virtual void loadAsset();
-	bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
+	void updateTitleButtons() override;
+	void loadAsset() override;
+	bool saveIfNeeded(LLInventoryItem* copyitem = NULL, bool sync = true);
 
 	void deleteNotecard();
 
@@ -89,6 +92,8 @@ class LLPreviewNotecard : public LLPreview
 
 	static void onClickDelete(void* data);
 
+	static void onClickEdit(void* data);
+
 	static void onSaveComplete(const LLUUID& asset_uuid,
 							   void* user_data,
 							   S32 status, LLExtStat ext_status);
@@ -99,6 +104,12 @@ class LLPreviewNotecard : public LLPreview
     static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
     static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
 
+    void openInExternalEditor();
+    bool onExternalChange(const std::string& filename);
+    bool loadNotecardText(const std::string& filename);
+    bool writeToFile(const std::string& filename);
+    std::string getTmpFileName();
+
 protected:
 	LLViewerTextEditor* mEditor;
 	LLButton* mSaveBtn;
@@ -106,6 +117,8 @@ class LLPreviewNotecard : public LLPreview
 	LLUUID mAssetID;
 
 	LLUUID mObjectID;
+
+	LLLiveLSLFile* mLiveFile;
 };
 
 
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 60099b08b7f63664e461429443c20c80beaf5ed2..d177384b5ac8c602b19d64e0b0c919d06aabac0f 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -41,7 +41,6 @@
 #include "llinventorymodel.h"
 #include "llkeyboard.h"
 #include "lllineeditor.h"
-#include "lllivefile.h"
 #include "llhelp.h"
 #include "llnotificationsutil.h"
 #include "llresmgr.h"
@@ -120,22 +119,6 @@ static bool have_script_upload_cap(LLUUID& object_id)
 /// ---------------------------------------------------------------------------
 /// LLLiveLSLFile
 /// ---------------------------------------------------------------------------
-class LLLiveLSLFile : public LLLiveFile
-{
-public:
-	typedef boost::function<bool (const std::string& filename)> change_callback_t;
-
-	LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
-	~LLLiveLSLFile();
-
-	void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
-
-protected:
-	/*virtual*/ bool loadFile();
-
-	change_callback_t	mOnChangeCallback;
-	bool				mIgnoreNextUpdate;
-};
 
 LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb)
 :	mOnChangeCallback(change_cb)
@@ -1069,7 +1052,7 @@ void LLScriptEdCore::openInExternalEditor()
 		{
 			if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
 			{
-				msg = getString("external_editor_not_set");
+				msg = LLTrans::getString("ExternalEditorNotSet");
 			}
 			else
 			{
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 69cf9d915838d21590edbb48f1fce80ea2f6dd2b..74e4c00d43bed537b9dd743ca37ec226f20c54c3 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,6 +34,7 @@
 #include "lliconctrl.h"
 #include "llframetimer.h"
 #include "llfloatergotoline.h"
+#include "lllivefile.h"
 #include "llsyntaxid.h"
 
 class LLLiveLSLFile;
@@ -53,6 +54,23 @@ class LLScriptEdContainer;
 class LLFloaterGotoLine;
 class LLFloaterExperienceProfile;
 
+class LLLiveLSLFile : public LLLiveFile
+{
+public:
+    typedef boost::function<bool(const std::string& filename)> change_callback_t;
+
+    LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
+    ~LLLiveLSLFile();
+
+    void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
+
+protected:
+    /*virtual*/ bool loadFile();
+
+    change_callback_t	mOnChangeCallback;
+    bool				mIgnoreNextUpdate;
+};
+
 // Inner, implementation class.  LLPreviewScript and LLLiveLSLEditor each own one of these.
 class LLScriptEdCore : public LLPanel
 {
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index de90896548b12fe008cf442f1b140e1d35e9c844..93143eb33fe6589ea898cbb0f21a23db81dd95b9 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
 	}
 }
 
-bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide)
 {
-	if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
+	if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu))
 		return false;
 
 	setNotHighlighted( );
 
-	bool bVisible(false);
-	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
-		bVisible |= (*itr)->hightlightAndHide( aFilter );
-
 	if( aFilter.empty() )
 	{
 		if( mCtrl )
@@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter
 		return true;
 	}
 
+	bool bHighlighted(!hide);
 	if( mLabel.find( aFilter ) != LLWString::npos )
 	{
 		if( mCtrl )
 			mCtrl->setHighlighted( true );
-		return true;
+		bHighlighted = true;
 	}
 
-	if( mCtrl && !bVisible )
+	bool bVisible(false);
+	for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
+		bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted);
+
+	if (mCtrl && !bVisible && !bHighlighted)
 	{
 		mWasHiddenBySearch = true;
 		mMenu->setVisible(FALSE);
 	}
-	return bVisible;
+	return bVisible || bHighlighted;
 }
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 42b2866fb6aacedc04c3f1947040f3f5cae63b08..9741557e49ea7b113ec74ce281e2803c727ec28c 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -107,7 +107,7 @@ namespace ll
 			SearchableItem();
 
 			void setNotHighlighted( );
-			bool hightlightAndHide( LLWString const &aFilter );
+			bool hightlightAndHide( LLWString const &aFilter, bool hide = true );
 		};
 
 		struct SearchData
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 816515426a1690cf0cdbf8274f853b73fb0343b5..90f8f84ea4c3081e5b994975f2538a4305391e50 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -3864,6 +3864,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
 	return TRUE;
 }
 
+BOOL LLSelectMgr::isSelfAvatarSelected()
+{
+	if (mAllowSelectAvatar)
+	{
+		return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+	}
+	return FALSE;
+}
 
 //--------------------------------------------------------------------
 // Duplicate objects
@@ -3886,6 +3894,17 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
 		make_ui_sound("UISndInvalidOp");
 		return;
 	}
+	if (!canDuplicate())
+	{
+		LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true);
+		if (node)
+		{
+			LLSD args;
+			args["OBJ_NAME"] = node->mName;
+			LLNotificationsUtil::add("NoCopyPermsNoObject", args);
+			return;
+		}
+	}
 	LLDuplicateData	data;
 
 	data.offset = offset;
@@ -6765,8 +6784,28 @@ void LLSelectMgr::pauseAssociatedAvatars()
 			
         mSelectedObjects->mSelectType = getSelectTypeForObject(object);
 
+        bool is_attached = false;
         if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && 
-            isAgentAvatarValid() && object->getParent() != NULL)
+            isAgentAvatarValid())
+        {
+            // Selection can be obsolete, confirm that this is an attachment
+            LLViewerObject* parent = (LLViewerObject*)object->getParent();
+            while (parent != NULL)
+            {
+                if (parent->isAvatar())
+                {
+                    is_attached = true;
+                    break;
+                }
+                else
+                {
+                    parent = (LLViewerObject*)parent->getParent();
+                }
+            }
+        }
+
+
+        if (is_attached)
         {
             if (object->isAnimatedObject())
             {
@@ -6784,14 +6823,12 @@ void LLSelectMgr::pauseAssociatedAvatars()
                 mPauseRequests.push_back(gAgentAvatarp->requestPause());
             }
         }
-        else
+        else if (object && object->isAnimatedObject() && object->getControlAvatar())
         {
-            if (object && object->isAnimatedObject() && object->getControlAvatar())
-            {
-                // Is a non-attached animated object. Pause the control avatar.
-                mPauseRequests.push_back(object->getControlAvatar()->requestPause());
-            }
+            // Is a non-attached animated object. Pause the control avatar.
+            mPauseRequests.push_back(object->getControlAvatar()->requestPause());
         }
+
     }
 }
 
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0fee88036d80b5d45bec08e02b1c9b21353851..3e8bfdb00e597bf0953a493a2ab4c8542a7ce603 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -714,6 +714,8 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 
 	LLPermissions* findObjectPermissions(const LLViewerObject* object);
 
+	BOOL isSelfAvatarSelected();
+
 	void selectDelete();							// Delete on simulator
 	void selectForceDelete();			// just delete, no into trash
 	void selectDuplicate(const LLVector3& offset, BOOL select_copy);	// Duplicate on simulator
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 689734e36ab936d43c3d070fd16ee92eb7aa183d..ea7e6497927e8155e6520b69d177300311a035fe 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -564,6 +564,7 @@ void LLSidepanelInventory::updateVerbs()
 	mWearBtn->setEnabled(FALSE);
 	mPlayBtn->setVisible(FALSE);
 	mPlayBtn->setEnabled(FALSE);
+	mPlayBtn->setToolTip(std::string(""));
  	mTeleportBtn->setVisible(FALSE);
  	mTeleportBtn->setEnabled(FALSE);
  	mShopBtn->setVisible(TRUE);
@@ -588,11 +589,23 @@ void LLSidepanelInventory::updateVerbs()
 		 	mShopBtn->setVisible(FALSE);
 			break;
 		case LLInventoryType::IT_SOUND:
+			mPlayBtn->setVisible(TRUE);
+			mPlayBtn->setEnabled(TRUE);
+			mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip"));
+			mShopBtn->setVisible(FALSE);
+			break;
 		case LLInventoryType::IT_GESTURE:
+			mPlayBtn->setVisible(TRUE);
+			mPlayBtn->setEnabled(TRUE);
+			mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip"));
+			mShopBtn->setVisible(FALSE);
+			break;
 		case LLInventoryType::IT_ANIMATION:
 			mPlayBtn->setVisible(TRUE);
 			mPlayBtn->setEnabled(TRUE);
-		 	mShopBtn->setVisible(FALSE);
+			mPlayBtn->setEnabled(TRUE);
+			mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip"));
+			mShopBtn->setVisible(FALSE);
 			break;
 		case LLInventoryType::IT_LANDMARK:
 			mTeleportBtn->setVisible(TRUE);
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 5a40af14a3c8239485915626280fa58aef838361..f5fea9decef5f9593eee9eef255b1064fe60f40c 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -34,7 +34,6 @@
 #include "lleconomy.h"
 #include "llfloaterperms.h"
 #include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
 #include "llfloaterflickr.h"
 #include "llfloatertwitter.h"
 #include "llimagefilter.h"
@@ -572,7 +571,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
     
     if (mThumbnailSubsampled)
     {
-        // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
+        // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
 		raw->resize( mPreviewImage->getWidth(),
                      mPreviewImage->getHeight(),
                      mPreviewImage->getComponents());
@@ -638,7 +637,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage()
     
 	if (raw)
 	{
-        // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
+        // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
         mBigThumbnailWidth = mPreviewImage->getWidth();
         mBigThumbnailHeight = mPreviewImage->getHeight();
         raw->resize( mBigThumbnailWidth,
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index d28a7cc048859852fc0622d4d3f63881eeb52b17..f6cf714db4c8d7b34ab649c5adda311b7cd4c5bf 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -99,7 +99,7 @@ void LLSurfacePatch::dirty()
 	}
 	else
 	{
-		LL_WARNS() << "No viewer object for this surface patch!" << LL_ENDL;
+		LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
 	}
 
 	mDirtyZStats = TRUE;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index c9133338fb1a2b24326f679af33dc1208b220100..f6cb787156cdc8e742614c0ae7d29e3f4e1c54b6 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -66,6 +66,7 @@ bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
 
 LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
 LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
+LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
 
 LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
 LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency");
@@ -1311,6 +1312,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
 							   << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
 							   << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
+			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
 		}
 		else
 		{
@@ -1326,7 +1328,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				LL_DEBUGS(LOG_TXT) << mID << ": Not in Cache" << LL_ENDL;
 				setState(LOAD_FROM_NETWORK);
 			}
-			
+			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
 			// fall through
 		}
 	}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index a01c01847ec3abd7cc6ca9ef2b9fbb9d5acf07b5..cdf886859703e13267f87f562ba585ccba6743af 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -312,6 +312,7 @@ class LLTextureFetch : public LLWorkerThread
     static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency;
     static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency;
     static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency;
+    static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate;
 
 private:
 	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 392c103d7c2021ddcedc832c205ed7aa85d7c6e1..f9c327b46e8a7f511bd4f23333fe61e6e905b1c7 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
 BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	mMouseDown = TRUE;
-	gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
+	gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build"));
 	return TRUE;
 }
 
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 276d24e9ed61afc9e07fb1f6f3ffc237f30a24b3..54df5198c8c95a18d5e5e453a6c65486c6bfa98f 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -111,9 +111,64 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
     mMouseOutsideSlop = FALSE;
 	mMouseDownX = x;
 	mMouseDownY = y;
+	LLTimer pick_timer;
+	BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
+	LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged);
+	LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
+	LLViewerObject *transp_object = transparent_pick.getObject();
+	LLViewerObject *visible_object = visible_pick.getObject();
+
+	// Current set of priorities
+	// 1. Transparent attachment pick
+	// 2. Transparent actionable pick
+	// 3. Visible attachment pick (e.x we click on attachment under invisible floor)
+	// 4. Visible actionable pick
+	// 5. Transparent pick (e.x. movement on transparent object/floor, our default pick)
+	// left mouse down always picks transparent (but see handleMouseUp).
+	// Also see LLToolPie::handleHover() - priorities are a bit different there.
+	// Todo: we need a more consistent set of rules to work with
+	if (transp_object == visible_object || !visible_object)
+	{
+		// Note: if transparent object is null, then visible object is also null
+		// since transparent pick includes non-tranpsarent one.
+		// !transparent_object check will be covered by transparent_object == visible_object.
+		mPick = transparent_pick;
+	}
+	else
+	{
+		// Select between two non-null picks
+		LLViewerObject *transp_parent = transp_object->getRootEdit();
+		LLViewerObject *visible_parent = visible_object->getRootEdit();
+		if (transp_object->isAttachment())
+		{
+			// 1. Transparent attachment
+			mPick = transparent_pick;
+		}
+		else if (transp_object->getClickAction() != CLICK_ACTION_DISABLED
+				 && (useClickAction(mask, transp_object, transp_parent) || transp_object->flagHandleTouch() || (transp_parent && transp_parent->flagHandleTouch())))
+		{
+			// 2. Transparent actionable pick
+			mPick = transparent_pick;
+		}
+		else if (visible_object->isAttachment())
+		{
+			// 3. Visible attachment pick
+			mPick = visible_pick;
+		}
+		else if (visible_object->getClickAction() != CLICK_ACTION_DISABLED
+				 && (useClickAction(mask, visible_object, visible_parent) || visible_object->flagHandleTouch() || (visible_parent && visible_parent->flagHandleTouch())))
+		{
+			// 4. Visible actionable pick
+			mPick = visible_pick;
+		}
+		else
+		{
+			// 5. Default: transparent
+			mPick = transparent_pick;
+		}
+	}
+	LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
 
-	//left mouse down always picks transparent (but see handleMouseUp)
-	mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
 	mPick.mKeyMask = mask;
 
 	mMouseButtonDown = true;
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 1936e2476102ffc1b496b4cd6e200e66eb135686..e424983cf81668cfffa00a4b2a3af050969a511a 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -38,8 +38,12 @@
 #include "llcoros.h"
 #include "reader.h"
 #include "llcorehttputil.h"
+#include "llurlregistry.h"
 
 
+static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">");
+static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>");
+
 /**
 * Handler of an HTTP machine translation service.
 *
@@ -99,6 +103,8 @@ class LLTranslationAPIHandler
     */
     virtual bool isConfigured() const = 0;
 
+    virtual LLTranslate::EService getCurrentService() = 0;
+
     virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0;
     virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure);
 
@@ -248,6 +254,8 @@ class LLGoogleTranslationHandler : public LLTranslationAPIHandler
         std::string& err_msg) const;
     /*virtual*/ bool isConfigured() const;
 
+    /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; }
+
     /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
 
 private:
@@ -409,6 +417,8 @@ class LLBingTranslationHandler : public LLTranslationAPIHandler
         std::string& err_msg) const;
     /*virtual*/ bool isConfigured() const;
 
+    /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; }
+
     /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
 private:
     static std::string getAPIKey();
@@ -520,7 +530,59 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri
 {
     LLTranslationAPIHandler& handler = getPreferredHandler();
 
-    handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), mesg, success, failure);
+    handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), addNoTranslateTags(mesg), success, failure);
+}
+
+std::string LLTranslate::addNoTranslateTags(std::string mesg)
+{
+    if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+    {
+        return mesg;
+    }
+
+    std::string upd_msg(mesg);
+    LLUrlMatch match;
+    S32 dif = 0;
+    //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation
+    while (LLUrlRegistry::instance().findUrl(mesg, match))
+    {
+        upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG);
+        upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG);
+        mesg.erase(match.getStart(), match.getEnd() - match.getStart());
+        dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size();
+    }
+    return upd_msg;
+}
+
+std::string LLTranslate::removeNoTranslateTags(std::string mesg)
+{
+    if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+    {
+        return mesg;
+    }
+    std::string upd_msg(mesg);
+    LLUrlMatch match;
+    S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size();
+    S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size();
+    S32 dif = 0;
+    //remove 'no-translate' tags we added to the links before
+    while (LLUrlRegistry::instance().findUrl(mesg, match))
+    {
+        if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG)
+        {
+            upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size);
+            dif -= opening_tag_size;
+
+            if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG)
+            {
+                upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " ");
+                dif -= closing_tag_size - 1;
+            }
+        }
+        mesg.erase(match.getStart(), match.getUrl().size());
+        dif += match.getUrl().size();
+    }
+    return upd_msg;
 }
 
 /*static*/
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index bf431cdfbb23ca2d983cdb1bc779f2ee4f6c9e9e..e0722fbd83f92dce9b41c58012e19875893d6621 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -91,6 +91,9 @@ public :
 	 */
 	static bool isTranslationConfigured();
 
+    static std::string addNoTranslateTags(std::string mesg);
+    static std::string removeNoTranslateTags(std::string mesg);
+
 private:
 	static LLTranslationAPIHandler& getPreferredHandler();
 	static LLTranslationAPIHandler& getHandler(EService service);
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index 5d598aaebe3ebd0369e685fb582fcb42ab02a646..b2d2fa9d77fbbec1baa0cef58745a87b5ea1c77e 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -28,6 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "lltwitterconnect.h"
+#include "llflickrconnect.h"
 
 #include "llagent.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
@@ -65,6 +66,49 @@ void toast_user_for_twitter_success()
     LLNotificationsUtil::add("TwitterConnect", args);
 }
 
+class LLTwitterConnectHandler : public LLCommandHandler
+{
+public:
+    LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {}
+
+    bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
+    {
+        if (tokens.size() >= 1)
+        {
+            if (tokens[0].asString() == "connect")
+            {
+                if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
+                {
+                    // this command probably came from the twitter_web browser, so close it
+                    LLFloaterReg::hideInstance("twitter_web");
+
+                    // connect to twitter
+                    if (query_map.has("oauth_token"))
+                    {
+                        LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
+                    }
+                    return true;
+                }
+                else if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
+                {
+                    // this command probably came from the flickr_web browser, so close it
+                    LLFloaterReg::hideInstance("flickr_web");
+
+                    // connect to flickr
+                    if (query_map.has("oauth_token"))
+                    {
+                        LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+};
+LLTwitterConnectHandler gTwitterConnectHandler;
+
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 794326e752f1054714c475d486649f6f65b7d5ab..a1670351f4005da600c0e90a9470dba1eadcd4b0 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -47,6 +47,7 @@
 // library includes
 #include "llnotificationsutil.h"
 #include "llsd.h"
+#include "stringize.h"
 
 static LLURLDispatcherListener sURLDispatcherListener;
 
@@ -255,14 +256,23 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL&
 // Teleportation links are handled here because they are tightly coupled
 // to SLURL parsing and sim-fragment parsing
 
-class LLTeleportHandler : public LLCommandHandler
+class LLTeleportHandler : public LLCommandHandler, public LLEventAPI
 {
 public:
 	// Teleport requests *must* come from a trusted browser
 	// inside the app, otherwise a malicious web page could
 	// cause a constant teleport loop.  JC
-	LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { }
-
+	LLTeleportHandler() :
+		LLCommandHandler("teleport", UNTRUSTED_THROTTLE),
+		LLEventAPI("LLTeleportHandler", "Low-level teleport API")
+	{
+		LLEventAPI::add("teleport",
+						"Teleport to specified [\"regionname\"] at\n"
+						"specified region-relative [\"x\"], [\"y\"], [\"z\"].\n"
+						"If [\"regionname\"] omitted, teleport to GLOBAL\n"
+						"coordinates [\"x\"], [\"y\"], [\"z\"].",
+						&LLTeleportHandler::from_event);
+	}
 
 	bool handle(const LLSD& tokens, const LLSD& query_map,
 				LLMediaCtrl* web)
@@ -293,6 +303,41 @@ class LLTeleportHandler : public LLCommandHandler
 		return true;
 	}
 
+	void from_event(const LLSD& params) const
+	{
+		Response response(LLSD(), params);
+		if (params.has("regionname"))
+		{
+			// region specified, coordinates (if any) are region-local
+			LLVector3 local_pos(
+				params.has("x")? params["x"].asReal() : 128,
+				params.has("y")? params["y"].asReal() : 128,
+				params.has("z")? params["z"].asReal() : 0);
+			std::string regionname(params["regionname"]);
+			std::string destination(LLSLURL(regionname, local_pos).getSLURLString());
+			// have to resolve region's global coordinates first
+			teleport_via_slapp(regionname, destination);
+			response["message"] = "Teleporting to " + destination;
+		}
+		else                        // no regionname
+		{
+			// coordinates are global, and at least (x, y) are required
+			if (! (params.has("x") && params.has("y")))
+			{
+				return response.error("Specify either regionname or global (x, y)");
+			}
+			LLVector3d global_pos(params["x"].asReal(), params["y"].asReal(),
+								  params["z"].asReal());
+			gAgent.teleportViaLocation(global_pos);
+			LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+			if (instance)
+			{
+				instance->trackLocation(global_pos);
+			}
+			response["message"] = STRINGIZE("Teleporting to global " << global_pos);
+		}
+	}
+
 	static void teleport_via_slapp(std::string region_name, std::string callback_url)
 	{
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index e1409d31ce085f386781eee10433415802f59370..3bbf3ace92bb980400af8faf4b09e907e568eb66 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -237,6 +237,7 @@ void display_stats()
 
 static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
 static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD");
 static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky");
 static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
@@ -568,6 +569,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	if (gDisconnected)
 	{
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
+		LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
 		render_ui();
 		swap();
 	}
@@ -1293,7 +1295,8 @@ void render_ui(F32 zoom_factor, int subfield)
 		{
 			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
 		}
-		
+
+		LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
 		render_hud_elements();
 		render_hud_attachments();
 	}
@@ -1308,8 +1311,6 @@ void render_ui(F32 zoom_factor, int subfield)
 		gGL.color4f(1,1,1,1);
 		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 		{
-			LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
-
 			if (!gDisconnected)
 			{
 				render_ui_3d();
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 2a61c26b30d3d1ff6b3503c52733a44e8979e5b0..f475ab7d6630248e13fda8a6be7e8d6adc46f678 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -67,7 +67,6 @@
 #include "llfloaterexperiences.h"
 #include "llfloaterexperiencepicker.h"
 #include "llfloaterevent.h"
-#include "llfloaterfacebook.h"
 #include "llfloaterflickr.h"
 #include "llfloaterfonttest.h"
 #include "llfloatergesture.h"
@@ -353,11 +352,9 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
 	LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
 
-	LLFloaterReg::add("fbc_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
 	LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
 	LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
 	
-	LLFloaterReg::add("facebook", "floater_facebook.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFacebook>);
 	LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
 	LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>);
 	LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index b89e1497a188d1b5435e377275090c1faf340f5d..e930eb20d3cf185affae53bb182d622dc0a0b2d3 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -64,7 +64,12 @@ LLViewerKeyboard gViewerKeyboard;
 
 void agent_jump( EKeystate s )
 {
-	if( KEYSTATE_UP == s  ) return;
+	static BOOL first_fly_attempt(TRUE);
+	if (KEYSTATE_UP == s)
+	{
+		first_fly_attempt = TRUE;
+		return;
+	}
 	F32 time = gKeyboard->getCurKeyElapsedTime();
 	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
 
@@ -77,7 +82,8 @@ void agent_jump( EKeystate s )
 	}
 	else
 	{
-		gAgent.setFlying(TRUE);
+		gAgent.setFlying(TRUE, first_fly_attempt);
+		first_fly_attempt = FALSE;
 		gAgent.moveUp(1);
 	}
 }
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 857799889bb871c066363f6da01c0d05bf89b044..6cfc22a4e596d31141c5527f7f6541c04f8ef5d0 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1683,7 +1683,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 
 	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
 	// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
-    // Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others)
+    // Do not use a spare if launching with full viewer control (e.g. Twitter and few others)
 	if ((plugin_basename == "media_plugin_cef") &&
         !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser)
 	{
@@ -1877,21 +1877,8 @@ void LLViewerMediaImpl::loadURI()
 		// trim whitespace from front and back of URL - fixes EXT-5363
 		LLStringUtil::trim( mMediaURL );
 
-		// *HACK: we don't know if the URI coming in is properly escaped
-		// (the contract doesn't specify whether it is escaped or not.
-		// but LLQtWebKit expects it to be, so we do our best to encode
-		// special characters)
-		// The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt
-		// Note especially that '%' and '/' are there.
-		std::string uri = LLURI::escape(mMediaURL,
-										"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-										"0123456789"
-										"$-_.+"
-										"!*'(),"
-										"{}|\\^~[]`"
-										"<>#%"
-										";/?:@&=",
-										false);
+		// URI often comes unescaped
+		std::string uri = LLURI::escapePathAndData(mMediaURL);
         {
             // Do not log the query parts
             LLURI u(uri);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index f1c073ed84cbbf38e07b7fd0227b5f6f1b1bf2fc..dc82719109b91d3bee6f9c9c89c11c8d97c28ade 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -54,7 +54,6 @@
 #include "lldaycyclemanager.h"
 #include "lldebugview.h"
 #include "llenvmanager.h"
-#include "llfacebookconnect.h"
 #include "llfilepicker.h"
 #include "llfirstuse.h"
 #include "llfloaterabout.h"
@@ -4066,10 +4065,8 @@ void near_sit_down_point(BOOL success, void *)
 	if (success)
 	{
 		gAgent.setFlying(FALSE);
+		gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
 		gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
-
-		// Might be first sit
-		//LLFirstUse::useSit();
 	}
 }
 
@@ -4754,6 +4751,12 @@ void handle_take()
 				category_id.setNull();
 			}
 
+			// check inbox
+			const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+			if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id))
+			{
+				category_id.setNull();
+			}
 		}
 	}
 	if(category_id.isNull())
@@ -9206,7 +9209,6 @@ void initialize_menus()
 	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
 
 	view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
-	enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
 
 	enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f42c4c3c51d702f3271472cfc38b1af11a5b27c3..18b71edc1bdf9d4502ebb8e74f2a10c10bbf2077 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2415,7 +2415,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std:
         && ((detected_language.empty()) || (expectLang != detected_language))
         && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0))
     {
-        chat.mText += " (" + translation + ")";
+        chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")";
     }
 
     LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 439f675a2d01ba58971d83178f6247cc5a98239b..5b227c641bcaf6273feae67e39119fedff736edb 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2895,7 +2895,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("EstateAccess");
 	capabilityNames.append("EstateChangeInfo");
 	capabilityNames.append("EventQueueGet");
-	capabilityNames.append("FacebookConnect");
 	capabilityNames.append("FlickrConnect");
 	capabilityNames.append("TwitterConnect");
 
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index f39275af21bd60d7f8103240ac0ee78152343095..ae55c6f39ba0d54cb0cddc2081f4f0f247a2b4b2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1219,6 +1219,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
         F32 cachReadTime = fastCacheTimer.getElapsedTimeF32();
 
         add(LLTextureFetch::sCacheHit, 1.0);
+        record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
         sample(LLTextureFetch::sCacheReadLatency, cachReadTime);
 
 		mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
@@ -1251,6 +1252,10 @@ void LLViewerFetchedTexture::loadFromFastCache()
 			addToCreateTexture();
 		}
 	}
+    else
+    {
+        record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
+    }
 }
 
 void LLViewerFetchedTexture::setForSculpt()
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 4308405c64225ff186ad4059f0a2b6aab61986e3..06524847d1780783df9272812a8d2a33f24b2148 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -512,7 +512,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 		if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM)
 		{
 			// Workaround: we need BOOST_ALM texture for something, 'rise' to NONE
-			imagep->setDecodePriority(LLViewerTexture::BOOST_NONE);
+			imagep->setBoostLevel(LLViewerTexture::BOOST_NONE);
 		}
 
 		LLViewerFetchedTexture *texture = imagep.get();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 543d17eb41fb5bf87180237a4515e106485ed862..d9636aadbe8e30854fcb7e616c467f4ce89facb8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3817,7 +3817,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 
 					BOOL draw_handles = TRUE;
 
-					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move)
+					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
 					{
 						draw_handles = FALSE;
 					}
@@ -4732,6 +4732,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 				{
 					// Required for showing the GUI in snapshots and performing bloom composite overlay
 					// Call even if show_ui is FALSE
+					LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
 					render_ui(scale_factor, subfield);
 					swap();
 				}
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c4430f4308933ad7022abde119912ccca1b723fa..c63c5f6b23b9ffd04961f49c1f1cc27f25fd2016 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -99,6 +99,8 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id)
 	{
 		return;
 	}
+	// This is terrain texture, but we are not setting it as BOOST_TERRAIN
+	// since we will be manipulating it later as needed.
 	mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
 	mDetailTextures[corner]->setNoDelete() ;
 	mRawImages[corner] = NULL;
@@ -241,6 +243,7 @@ BOOL LLVLComposition::generateComposition()
 			}
 			mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
 			mDetailTextures[i]->setMinDiscardLevel(ddiscard);
+			mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
 			return FALSE;
 		}
 	}
@@ -287,7 +290,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 				{
 					mDetailTextures[i]->destroyRawImage() ;
 				}
-				LL_DEBUGS() << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << LL_ENDL;
+				LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL;
 				return FALSE;
 			}
 
@@ -323,12 +326,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 
 	if (x_end > mWidth)
 	{
-		LL_WARNS() << "x end > width" << LL_ENDL;
+		LL_WARNS("Terrain") << "x end > width" << LL_ENDL;
 		x_end = mWidth;
 	}
 	if (y_end > mWidth)
 	{
-		LL_WARNS() << "y end > width" << LL_ENDL;
+		LL_WARNS("Terrain") << "y end > width" << LL_ENDL;
 		y_end = mWidth;
 	}
 
@@ -358,7 +361,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 	
 	if (tex_comps != st_comps)
 	{
-		LL_WARNS() << "Base texture comps != input texture comps" << LL_ENDL;
+		LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL;
 		return FALSE;
 	}
 
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 0d3f65502ad8986c13cc15e51025ead5875cea4a..e10ba77e16ba71883ffdb7ab8e6e95ef75d0ac49 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -658,6 +658,8 @@ void LLVivoxVoiceClient::voiceControlCoro()
     mIsCoroutineActive = true;
     LLCoros::set_consuming(true);
 
+    U32 retry = 0;
+
     while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
     {
         LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
@@ -666,7 +668,8 @@ void LLVivoxVoiceClient::voiceControlCoro()
 
     do
     {
-        if (startAndConnectSession())
+        bool success = startAndConnectSession();
+        if (success)
         {
             if (mTuningMode)
             {
@@ -677,6 +680,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
     
             LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;            
             endAndDisconnectSession();
+            retry = 0;
         }
         
         // if we hit this and mRelogRequested is true, that indicates
@@ -689,7 +693,19 @@ void LLVivoxVoiceClient::voiceControlCoro()
             << LL_ENDL;            
         if (mRelogRequested)
         {
-            LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
+            if (!success)
+            {
+                // We failed to connect, give it a bit time before retrying.
+                retry++;
+                F32 delay = llmin(5.f * (F32)retry, 60.f);
+                llcoro::suspendUntilTimeout(delay);
+                LL_INFOS("Voice") << "Voice failed to establish session after " << retry << " tries. Will attempt to reconnect." << LL_ENDL;
+            }
+            else
+            {
+                LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
+            }
+
             while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
             {
                 LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
@@ -770,12 +786,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     {
 #ifndef VIVOXDAEMON_REMOTEHOST
         // Launch the voice daemon
-        std::string exe_path = gDirUtilp->getAppRODataDir();
 #if LL_WINDOWS
+        // On windows use exe (not work or RO) directory
+        std::string exe_path = gDirUtilp->getExecutableDir();
         gDirUtilp->append(exe_path, "SLVoice.exe");
 #elif LL_DARWIN
+        // On MAC use resource directory
+        std::string exe_path = gDirUtilp->getAppRODataDir();
         gDirUtilp->append(exe_path, "SLVoice");
 #else
+        std::string exe_path = gDirUtilp->getExecutableDir();
         gDirUtilp->append(exe_path, "SLVoice");
 #endif
         // See if the vivox executable exists
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a72244929ec9f000802d224ba3e2161d9fad48f2..bd73c234a6a40d2f90fdcd13f702eea8937b2ce9 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4062,7 +4062,6 @@ void LLPipeline::postSort(LLCamera& camera)
 
 void render_hud_elements()
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
 	gPipeline.disableLights();		
 	
 	LLGLDisable fog(GL_FOG);
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 2f9fdabea3625b5f1affc2d7afb82c326d37b0e5..5aba0546f3cd042c79bb67d9feebe23232f37b1a 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -133,7 +133,6 @@ with the same filename but different name
   <texture name="Command_Chat_Icon"         file_name="toolbar_icons/chat.png"         preload="true" />
   <texture name="Command_Compass_Icon"      file_name="toolbar_icons/land.png"         preload="true" />
   <texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" />
-  <texture name="Command_Facebook_Icon"     file_name="toolbar_icons/facebook.png"     preload="true" />
   <texture name="Command_Flickr_Icon"       file_name="toolbar_icons/flickr.png"       preload="true" />
   <texture name="Command_Gestures_Icon"     file_name="toolbar_icons/gestures.png"     preload="true" />
   <texture name="Command_Grid_Status_Icon"  file_name="toolbar_icons/grid_status.png"  preload="true" />
@@ -205,8 +204,6 @@ with the same filename but different name
   <texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" />
   <texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" />
 
-  <texture name="Facebook_Icon" file_name="icons/Facebook.png" preload="false" />
-
   <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
 
   <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
@@ -593,7 +590,6 @@ with the same filename but different name
   <texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" />
   <texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" />
   <texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" />
-  <texture name="Snapshot_Facebook" file_name="toolbar_icons/facebook.png" preload="false" />
 
   <texture name="startup_logo"  file_name="windows/startup_logo.png" preload="true" />
 
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 1e18ab20e8266f5411017cf06f9b83bb0f72c205..2bff6d3e2fdf9a4b0d97c80325be9a252e8fbd2a 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -21,7 +21,7 @@
 	<floater.string name="Remaining">
 		Restzeit
 	</floater.string>
-	<tab_container name="landtab" tab_min_width="40" width="489">
+	<tab_container name="landtab" tab_min_width="40">
 		<panel label="ALLGEMEIN" name="land_general_panel">
 			<panel.string name="new users only">
 				Nur neue Benutzer
@@ -361,8 +361,8 @@ Nur große Parzellen können in der Suche aufgeführt werden.
 			<text name="landing_point">
 				Landepunkt: [LANDING]
 			</text>
-			<button label="Festlegen" label_selected="Festlegen" left="234" name="Set" right="-88" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/>
-			<button label="Löschen" label_selected="Löschen" left="312" name="Clear" tool_tip="Landepunkt löschen" width="70"/>
+			<button label="Festlegen" label_selected="Festlegen" name="Set" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/>
+			<button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Landepunkt löschen" width="70"/>
 			<text name="Teleport Routing: ">
 				Teleport-Route:
 			</text>
@@ -433,7 +433,7 @@ Nur große Parzellen können in der Suche aufgeführt werden.
 			<panel.string name="estate_override">
 				Eine oder mehrere dieser Optionen gelten auf Grundbesitzebene
 			</panel.string>
-			<check_box label="Alle Besucher sind zugelassen (Bei Deaktivierung dieser Option werden Bannlinien generiert)" name="public_access"/>
+			<check_box label="Alle Besucher sind zugelassen" tool_tip="Bei Deaktivierung dieser Option werden Bannlinien generiert" name="public_access"/>
 			<check_box label="Muss 18+ sein [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/>
 			<check_box label="Muss über Zahlungsinfo in Datei [ESTATE_PAYMENT_LIMIT] verfügen" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
 			<check_box label="Gruppe [GROUP] ohne Beschränkungen zulassen" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index d04e738b2205999992affecb82ee703e9bb27ad6..9f853fd960032489b51aa10169fd5cff2818da9b 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -163,6 +163,7 @@
              layout="topleft"
              left_pad="2"
              name="Description"
+             spellcheck="true"
              top_delta="0"
              width="365"
              word_wrap="true" />
@@ -1268,6 +1269,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="edit objects check"
+             tool_tip="If checked, Residents can create and rez objects on your land."
              width="130" />
             <check_box
              height="16"
@@ -1275,6 +1277,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="edit group objects check"
+             tool_tip="If checked, parcel group members can create and rez objects on your land."
              width="70" />
             <text
              type="string"
@@ -1293,6 +1296,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="all object entry check"
+             tool_tip="If checked, Residents can move existing objects from other parcels onto this parcel."
              top_delta="0"
              width="130" />
             <check_box
@@ -1301,6 +1305,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="group object entry check"
+             tool_tip="If checked, parcel group members can move existing objects from other parcels onto this parcel."
              top_delta="0"
              width="70" />
             <text
@@ -1320,6 +1325,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="check other scripts"
+             tool_tip="If checked, Residents can run scripts on your parcel, including attachments."
              top_delta="0"
              width="130" />
             <check_box
@@ -1328,6 +1334,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left_pad="2"
              name="check group scripts"
+             tool_tip="If checked, parcel group members can run scripts on your parcel, including attachments."
              top_delta="0"
              width="70" />
           <panel
@@ -1466,11 +1473,12 @@ Only large parcels can be listed in search.
              length="1"
              follows="left|top"
              text_color="LtGray"
+             text_readonly_color="LabelDisabledColor"
              height="32"
              layout="topleft"
              left="274"
              top="150"
-             name="allow_label5"
+             name="allow_see_label"
              width="205"
              word_wrap="true">
               Avatars on other parcels can see and chat with avatars on this parcel
@@ -1908,6 +1916,7 @@ Only large parcels can be listed in search.
              layout="topleft"
              left="8"
              name="public_access"
+             tool_tip=""
              label="Anyone can visit (Unchecking this will create ban lines)"
              top_pad="10" 
              width="278" />
diff --git a/indra/newview/skins/default/xui/en/floater_ban_duration.xml b/indra/newview/skins/default/xui/en/floater_ban_duration.xml
index 5562f288774f8533e1499485c1e438fdf7b785db..6c537cc08d140b23dc111175c6f862a73aae9431 100644
--- a/indra/newview/skins/default/xui/en/floater_ban_duration.xml
+++ b/indra/newview/skins/default/xui/en/floater_ban_duration.xml
@@ -28,12 +28,12 @@
     draw_border="false"
     enabled="true"
     follows="left|top"
-    height="40"
+    height="47"
     left="20"
     mouse_opaque="true"
     name="ban_duration_radio"
     tab_stop="true"
-    width="200">
+    width="150">
        <radio_item
         type="string"
         follows="left|top"
@@ -75,7 +75,7 @@
     left_delta="70"
     name="hours_textbox"
     top_delta="5"
-    width="75">
+    width="70">
         hours.
    </text>
     
diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
index 2dfba1ac448e8f71123e97f54715d565a2860946..f275fec066e6968bd33f70a7517701e625a9c0b4 100644
--- a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
+++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
@@ -493,6 +493,7 @@
             layout="topleft"
             left="11"
             name="edit_experience_description"
+            spellcheck="true"
             max_length="2048"
             text_color="black"
             right="-11"
diff --git a/indra/newview/skins/default/xui/en/floater_facebook.xml b/indra/newview/skins/default/xui/en/floater_facebook.xml
deleted file mode 100644
index b34d70516af376f85194e33f6e92e75e67f72df9..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_facebook.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
-  positioning="cascading"
-  can_close="true"
-  help_topic="floater_facebook"
-  layout="topleft"
-  name="floater_facebook"
-  save_rect="true"
-  single_instance="true"
-  reuse_instance="true"
-  title="POST TO FACEBOOK"
-  min_height="462"
-  min_width="304"
-  height="462"
-  width="272">
-   <tab_container
-     name="tabs"
-     tab_group="1"
-     tab_min_width="64"
-     tab_height="21"
-     tab_position="top"
-     top="7"
-     height="437"
-     follows="all"
-     halign="center">
-     <panel
-       filename="panel_facebook_status.xml"
-       class="llfacebookstatuspanel"
-       follows="all"
-       label="STATUS"
-       name="panel_facebook_status"/>
-     <panel
-       filename="panel_facebook_photo.xml"
-       class="llfacebookphotopanel"
-       follows="all"
-       label="PHOTO"
-       name="panel_facebook_photo"/>
-     <panel
-       filename="panel_facebook_place.xml"
-       class="llfacebookcheckinpanel"
-       follows="all"
-       label="CHECK IN"
-       name="panel_facebook_place"/>
-     <panel
-       filename="panel_facebook_friends.xml"
-       class="llfacebookfriendspanel"
-       follows="all"
-       label="FRIENDS"
-       name="panel_facebook_friends"/>
-     <!--<panel
-       filename="panel_facebook_account.xml"
-       class="llfacebookaccountpanel"
-       follows="all"
-       label="ACCOUNT"
-       name="panel_facebook_account"/>-->
-   </tab_container>
-     <text
-      name="connection_error_text"
-      type="string"
-      follows="left|bottom|right"
-      bottom="-5"
-      left="10"
-      width="250"
-      height="20"
-      wrap="true"
-      halign="left"
-      valign="center"
-      text_color="DrYellow"
-      font="SansSerif">
-      Error
-     </text>
-     <loading_indicator
-      follows="left|bottom"
-      height="24"
-      width="24"
-      name="connection_loading_indicator"
-      top_delta="-2"
-      left="10"
-      visible="true"/>
-     <text
-      name="connection_loading_text"
-      type="string"
-      follows="left|bottom|right"
-      top_delta="2"
-      left_pad="5"
-      width="250"
-      height="20"
-      wrap="true"
-      halign="left"
-      valign="center"
-      text_color="EmphasisColor"
-      font="SansSerif">
-      Loading...
-    </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index fa7147d9cae52884a43cba37550959d98ccee93d..645003cc14e07613b6490e2d1f0a7cf7e37453ad 100644
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -60,10 +60,21 @@
                   min_width="100">
       <panel top="0"
              left="0"
-             width="220"
+             width="204"
              height="440"
              name="legend"
              follows="all"/>
+      <scroll_bar
+        top ="0"
+        right="-1"
+        height="440"
+        width="15"
+        follows="top|right|bottom"
+        name="scroll_vert"
+        orientation="vertical"
+        step_size="16"
+        doc_size="3000"
+          />
     </layout_panel>
     <layout_panel name="timers_panel"
                   auto_resize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 200e9b9537c2228ad07e799201ce8c3b84b999d4..9f051d9f8d8de9daea1e4a6044543bc9392df032 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -119,6 +119,7 @@
      follows="left|bottom"
      height="23"
      label="Edit"
+     tool_tip="Open window for editing selected gesture."
      layout="topleft"
      left="6"
      name="edit_btn"
@@ -128,6 +129,7 @@
      follows="left|bottom"
      height="23"
      label="Play"
+     tool_tip="Execute selected gesture in-world."
      layout="topleft"
      left_pad="6"
      name="play_btn"
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index 1b4992b4ca50d44baf53a8ce2741e38567df73fb..ca1d299553b81813f363901bc20b8f46697499eb 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -2,7 +2,7 @@
 <floater
  legacy_header_height="18"
  can_minimize="false"
- height="468"
+ height="448"
  layout="topleft"
  name="Inventory Finder"
  help_topic="inventory_finder"
@@ -110,23 +110,6 @@
      name="check_notecard"
      top_delta="0"
      width="126" />
-    <icon
-     height="16"
-     image_name="Inv_Mesh"
-     layout="topleft"
-     left="8"
-     mouse_opaque="true"
-     name="icon_mesh"
-     top="142"
-     width="16" />
-    <check_box
-     height="16"
-     label="Meshes"
-     layout="topleft"
-     left_pad="2"
-     name="check_mesh"
-     top_delta="0"
-     width="126" />
     <icon
      height="16"
      image_name="Inv_Object"
@@ -134,7 +117,7 @@
      left="8"
      mouse_opaque="true"
      name="icon_object"
-     top="162"
+     top="142"
      width="16" />
     <check_box
      height="16"
@@ -151,7 +134,7 @@
      left="8"
      mouse_opaque="true"
      name="icon_script"
-     top="182"
+     top="162"
      width="16" />
     <check_box
      height="16"
@@ -168,7 +151,7 @@
      left="8"
      mouse_opaque="true"
      name="icon_sound"
-     top="202"
+     top="182"
      width="16" />
     <check_box
      height="16"
@@ -185,7 +168,7 @@
      left="8"
      mouse_opaque="true"
      name="icon_texture"
-     top="222"
+     top="202"
      width="16" />
     <check_box
      height="16"
@@ -202,7 +185,7 @@
      left="8"
      mouse_opaque="true"
      name="icon_snapshot"
-     top="242"
+     top="222"
      width="16" />
     <check_box
      height="16"
@@ -220,7 +203,7 @@
      layout="topleft"
      left="8"
      name="All"
-     top="262"
+     top="242"
      width="100" />
     <button
      height="20"
@@ -274,7 +257,7 @@
      width="260"/>
     <check_box
      height="16"
-     top="352"
+     top="332"
      label="Since Logoff"
      layout="topleft"
      left_delta="0"
@@ -290,7 +273,7 @@
      layout="topleft"
      left_delta="0"
      name="- OR -"
-     top="370"
+     top="350"
      width="144">
         - OR -
     </text>
@@ -298,7 +281,7 @@
      height="16"
      layout="topleft"
      name="date_search_direction"
-     top="388"
+     top="368"
      left="8"
      width="270">
      <radio_item
@@ -368,6 +351,6 @@
      layout="topleft"
      name="Close"
      right="-6"
-     top="434"
+     top="414"
      width="76" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
index 93bfe53aae9193531c539f04310cbfd2b74018db..659033efd4192a40128586e6c3571dcb072cc801 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
@@ -58,12 +58,12 @@
 	 label_width="95"
 	 layout="topleft"
 	 left_delta="210"
-	 max_val="12000"
+	 max_val="65535"
 	 min_val="10"
 	 name="web_proxy_port"
 	 top_delta="0"
 	 tool_tip="The port of the HTTP proxy you would like to use."
-	 width="145" />
+	 width="150" />
 	<check_box
 	 control_name="Socks5ProxyEnabled"
 	 height="16"
@@ -111,11 +111,11 @@
 	 label_width="95"
 	 layout="topleft"
 	 left_delta="210"
-	 max_val="12000"
+	 max_val="65535"
 	 min_val="10"
 	 name="socks_proxy_port"
 	 top_delta="0"
-	 width="145"
+	 width="150"
 	 tool_tip="The port of the SOCKS 5 proxy you would like to use."
 	 commit_callback.function="Proxy.Change" />
 	<text
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 2e1c8ce6707354e69c065b7f5b4a779aadc76ea3..dcbdfa8794dc52ae23eff12b7d99f457b0fb6ebc 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -6,7 +6,7 @@
  height="361"
  layout="topleft"
  min_height="243"
- min_width="234"
+ min_width="330"
  name="preview notecard"
  help_topic="preview_notecard"
  title="NOTECARD:"
@@ -77,6 +77,16 @@
      word_wrap="true">
         Loading...
     </text_editor>
+      <button
+     follows="left|bottom"
+     height="22"
+     label="Edit..."
+     label_selected="Edit"
+     layout="topleft"
+     left="4"
+     name="Edit"
+     top="332"
+     width="100" />
     <button
      follows="right|bottom"
      height="22"
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 8fa5b49573527a5eb922fe4ecb574f8fda3feb45..d07e3cb31b20a5f03571220e85c5418dfb8b4bc5 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -246,7 +246,7 @@
          name="Land__Encroachment__Objects_textures"
          value="63" />        
         <combo_box.item
-         label="Gaming Policy Violation"
+         label="Skill Gaming Policy Violation"
          name="Wagering_gambling"
          value="67" />       
     </combo_box>
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index e50747cb5fea035bc6f13fabb9aa48ad23674e75..832c2ee7da62bfcb0c439653c4bc87d69a3987b4 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -23,10 +23,6 @@
      name="postcard_progress_str">
         Sending Email
     </string>
-    <string
-        name="facebook_progress_str">
-        Posting to Facebook
-    </string>
     <string
         name="profile_progress_str">
         Posting
@@ -39,10 +35,6 @@
      name="local_progress_str">
         Saving to Computer
     </string>
- 	<string
-        name="facebook_succeeded_str">
- 	    Image uploaded
- 	</string>
  	<string
         name="profile_succeeded_str">
  	    Image uploaded
@@ -60,10 +52,6 @@
  	    Saved to Computer!
  	</string>
  	<string
-     name="facebook_failed_str">
- 	    Failed to upload image to your Facebook timeline.
- 	</string>
- 	<string
      name="profile_failed_str">
  	    Failed to upload image to your Profile Feed.
  	</string>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 8b1d50e58f24b67d13ce4c75903ff48085c8e1bc..2d5263b78f7067538af627ce1110af0192e63686 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -10,6 +10,8 @@
       <file>simhei.ttf</file>
       <file>ArialUni.ttf</file>
       <file>msyh.ttc</file>
+      <file load_collection="true">Cambria.ttc</file>
+      <file>malgun.ttf</file>
     </os>
     <os name="Mac">
       <file>ヒラギノ角ゴシック W3.ttc</file>  
@@ -21,6 +23,7 @@
       <file>AppleSDGothicNeo-Regular.otf</file>
       <file>华文细黑.ttf</file>
       <file>PingFang.ttc</file>
+      <file>STIXGeneral.otf</file>
     </os>
   </font>
 
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f2ee9c6447556d6ba4d9f6ca41f5e41ec52fb7d0..7bb7b5d62cf2f0b2aa13be6aac1934435420cb65 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -306,13 +306,6 @@
              parameter="conversation" />
         </menu_item_check>
         <menu_item_separator/>
-      <menu_item_call
-        label="Facebook..."
-        name="Facebook">
-        <menu_item_call.on_click
-          function="Floater.Toggle"
-          parameter="facebook"/>
-      </menu_item_call>
       <menu_item_call
         label="Twitter..."
         name="Twitter">
@@ -1051,8 +1044,7 @@
            shortcut="control|D">
             <menu_item_call.on_click
                function="Object.Duplicate" />
-            <menu_item_call.on_enable
-               function="Object.EnableDuplicate" />
+
           </menu_item_call>
 		</menu>
         <menu
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index b7cd6517ea9a9910035c847a2fe00913834214c2..053c04184974d553b55c0f342029283c3f696e74 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6705,13 +6705,6 @@ Please select at least one type of content to search (General, Moderate, or Adul
 [MESSAGE]
   </notification>
 
- <notification
-  icon="notify.tga"
-  name="FacebookConnect"
-  type="notifytip">
-[MESSAGE]
- </notification>
-
   <notification
    icon="notify.tga"
    name="FlickrConnect"
@@ -8639,6 +8632,7 @@ Please check your network and firewall setup.
    icon="alertmodal.tga"
    name="NoVoiceConnect"
    type="alertmodal">
+    <unique/>
 We are unable to connect to the voice server:
 
 [HOSTID]
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml b/indra/newview/skins/default/xui/en/panel_facebook_friends.xml
deleted file mode 100644
index 97994fb08b6c3d05141d2e823af0228f01d07a59..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<panel
-	 height="400"
-	 width="272"
-	 layout="topleft"
-    follows="all"
-   name="panel_facebook_friends">
-  <string
-   name="facebook_friends_empty"
-   value="You currently do not have any Facebook friends who are also Second Life residents. Ask your Facebook friends to join Second Life today!" />
-  <string
-   name="facebook_friends_no_connected"
-   value="You're currently not connected to Facebook. Please go to the Status tab to connect and enable this feature." />
-  <accordion
- background_visible="false"
- bg_alpha_color="DkGray2"
- bg_opaque_color="DkGray2"
-   follows="all"
-   height="383"
-   layout="topleft"
-   left="10"
-   name="friends_accordion"
-   right="-10"
-   top_pad="2">
-    <accordion_tab
-     layout="topleft"
-     height="173"
-     name="tab_second_life_friends"
-     title="SL friends">
-      <avatar_list
-       ignore_online_status="true"
-       allow_select="true"
-       follows="all"
-       height="173"
-       layout="topleft"
-       left="0"
-       name="second_life_friends"
-       show_permissions_granted="true"
-       top="0"
-       width="272" />
-    </accordion_tab>
-    <accordion_tab
-     layout="topleft"
-     height="173"
-     name="tab_suggested_friends"
-     title="Add these people as SL friends">
-      <avatar_list
-       ignore_online_status="true"
-       allow_select="true"
-       follows="all"
-       height="173"
-       layout="topleft"
-       left="0"
-       name="suggested_friends"
-       show_permissions_granted="true"
-       top="0"
-       width="272" />
-    </accordion_tab>
-  </accordion>
-    <text
-        layout="topleft"
-        word_wrap="true"
-        height="64"
-        width="250"
-        follows="top|left|right"
-        font="SansSerif"
-        left="10"
-		right="-10"
-        name="facebook_friends_status"
-        top="5"
-        type="string">
-        Not connected to Facebook.
-    </text>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
deleted file mode 100644
index 22e6598352714a4b700c12bc4fa7e23e3beb05f1..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
+++ /dev/null
@@ -1,168 +0,0 @@
-    <panel
-      height="400"
-      width="272"
-      layout="topleft"
-      follows="all"
-      name="panel_facebook_photo">
-            <combo_box
-             control_name="FacebookPhotoResolution"
-             follows="left|top"
-			 layout="topleft"
-             top="7"
-             left="10"
-             name="resolution_combobox"
-             tool_tip="Image resolution"
-             height="21"
-             width="124">
-              <combo_box.item
-               label="Current Window"
-               name="CurrentWindow"
-               value="[i0,i0]" />
-              <combo_box.item
-               label="640x480"
-               name="640x480"
-               value="[i640,i480]" />
-              <combo_box.item
-               label="800x600"
-               name="800x600"
-               value="[i800,i600]" />
-              <combo_box.item
-               label="1024x768"
-               name="1024x768"
-               value="[i1024,i768]" />
-              <combo_box.item
-               label="1200x630"
-               name="1200x630"
-               value="[i1200,i630]" />
-            </combo_box>
-            <combo_box
-                control_name="FacebookPhotoFilters"
-                follows="left|top"
-				layout="topleft"
-                name="filters_combobox"
-                tool_tip="Image filters"
-                top="7"
-                left_pad="4"
-                height="21"
-                width="124">
-                <combo_box.item
-                label="No Filter"
-                name="NoFilter"
-                value="NoFilter" />
-            </combo_box>
-            <panel
-                height="150"
-                width="252"
-                visible="true"
-				layout="topleft"
-                name="thumbnail_placeholder"
-                top_pad="5"
-                follows="left|top|rith"
-				right="-10"
-                left="10">
-            </panel>
-			<text
-                follows="left|top"
-				layout="topleft"
-                font="SansSerif"
-                text_color="EmphasisColor"
-                height="14"
-                top_pad="2"
-                left="10"
-                length="1"
-                halign="center"
-                name="working_lbl"
-                translate="false"
-                type="string"
-                visible="true"
-                width="251">
-                Refreshing...
-            </text>
-			<view_border 
-			 bevel_style="in"
-			 follows="left|top"
-			 layout="topleft"
-			 height="1"
-			 left="10"
-			 name="refresh_border"
-			 width="250"
-			 top_pad="0"/>
-            <button
-             follows="left|top"
-			 layout="topleft"
-             height="23"
-             label="Refresh"
-             left="10"
-             top_pad="5"
-             name="new_snapshot_btn"
-             tool_tip="Click to refresh"
-             visible="true"
-             width="100" >
-             <button.commit_callback
-               function="SocialSharing.RefreshPhoto" />
-            </button>
-            <button
-                follows="right|top"
-				layout="topleft"
-                height="23"
-                label="Preview"
-                right="-10"
-                top_delta="0"
-                name="big_preview_btn"
-                tool_tip="Click to toggle preview"
-                is_toggle="true"
-                visible="true"
-                width="100" >
-                <button.commit_callback
-                function="SocialSharing.BigPreview" />
-            </button>
-            <text
-             length="1"
-             follows="top|left|right"
-			 layout="topleft"
-             font="SansSerif"
-             height="16"
-             left="10"
-             name="caption_label"
-             top_pad="20"
-             type="string">
-              Comment (optional):
-            </text>
-            <text_editor
-             follows="left|top|right|bottom"
-			 layout="topleft"
-             height="87"
-             width="250"
-             left="10"
-			 right="-10"
-             length="1"
-             max_length="700"
-             name="photo_caption"
-             type="string"
-             word_wrap="true">
-            </text_editor>
-          <button
-           follows="left|top"
-		   layout="topleft"
-           top_pad="22"
-           left="10"
-           height="23"
-           label="Post"
-           name="post_photo_btn"
-           width="100">
-            <button.commit_callback
-             function="SocialSharing.SendPhoto" />
-          </button>
-          <button
-               follows="right|top"
-			   layout="topleft"
-               height="23"
-               label="Cancel"
-               name="cancel_photo_btn"
-               right="-10"
-               top_delta="0"
-               width="100">
-            <button.commit_callback
-             function="SocialSharing.Cancel" />
-          </button>
-    </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_place.xml b/indra/newview/skins/default/xui/en/panel_facebook_place.xml
deleted file mode 100644
index f87b008c4ec53b7ef98655622d99fbf828c1baad..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_place.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-    <panel
-      height="400"
-      width="272"
-	  layout="topleft"
-      follows="all"
-      name="panel_facebook_place">
-          <text
-            length="1"
-            follows="top|left|right"
-			layout="topleft"
-            font="SansSerif"
-            height="16"
-            left="10"
-            name="place_caption_label"
-            top="5"
-            type="string">
-            Say something about where you are:
-          </text>
-          <text_editor
-            follows="top|left|right"
-			layout="topleft"
-            height="70"
-            width="250"
-            left="10"
-			right="-10"
-            length="1"
-            max_length="700"
-            name="place_caption"
-            type="string"
-            word_wrap="true">
-           </text_editor>
-		  <check_box
-              follows="left|top"
-			  layout="topleft"
-              initial_value="false"
-			  height="16"
-              top_pad="8"
-              width="8"
-              label="Include overhead view of location"
-              name="add_place_view_cb"
-              left="10"/>
-              <panel
-                  follows="left|top"
-				  layout="topleft"
-                  height="243"
-                  width="250"
-                  background_visible="true"
-                  bg_opaque_color="Black"
-                  bg_alpha_color="Black"
-                  top_pad="8"
-                  left="10"
-				  right="-12"
-                  visible="true"
-                  name="map_border">
-              </panel>
-              <icon
-                follows="left|top"
-				layout="topleft"
-                height="243"
-                width="250"
-                image_name="Map_Placeholder_Icon"
-                top_delta="0"
-				right="-12"
-                left="10"
-                visible="true"
-                name="map_placeholder">
-              </icon>
-              <icon
-                  follows="left|top"
-				  layout="topleft"
-                  height="243"
-                  width="250"
-                  image_name="Map_Placeholder_Icon"
-                  top_delta="0"
-                  left="10"
-				  right="-12"
-                  visible="true"
-                  name="map_default">
-              </icon>
-			  <loading_indicator
-              follows="left|top"
-			  layout="topleft"
-              height="24"
-              width="24"
-              name="map_loading_indicator"
-              top_delta="116"
-              left="126"
-              visible="false"/>
-            <button
-              follows="left|bottom"
-			  layout="topleft"
-              top_pad="95"
-              left="10"
-              height="23"
-              label="Post"
-              name="post_place_btn"
-              width="100">
-              <button.commit_callback
-                 function="SocialSharing.SendCheckin" />
-            </button>
-            <button
-              follows="right|bottom"
-			  layout="topleft"
-              height="23"
-              label="Cancel"
-              name="cancel_place_btn"
-              right="-10"
-              top_delta="0"
-              width="100">
-              <button.commit_callback
-                  function="SocialSharing.Cancel" />
-            </button>
-    </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_status.xml b/indra/newview/skins/default/xui/en/panel_facebook_status.xml
deleted file mode 100644
index fe0f3c9279f75bf4a5d7fb29049bd4969f8ead8f..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_status.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-    <panel
-	 height="400"
-	 width="272"
-     follows="all"
-	 layout="topleft"
-     name="panel_facebook_status">
-        <string
-      name="facebook_connected"
-      value="You are connected to Facebook as:" />
-  <string
-      name="facebook_disconnected"
-      value="Not connected to Facebook" />
-  <text
-   layout="topleft"
-   length="1"
-   follows="top|left"
-   font="SansSerif"
-   height="16"
-   left="10"
-   name="account_caption_label"
-   top="5"
-   type="string">
-    Not connected to Facebook.
-  </text>
-  <text
-   layout="topleft"
-   top_pad="2"
-   length="1"
-   follows="top|left"
-   font="SansSerif"
-   height="16"
-   left="10"
-   name="account_name_label"
-   parse_urls="true"
-   type="string"/>
-  <panel
-    layout="topleft"
-    follows="left|top"
-    name="panel_buttons"
-    height="60"
-    left="0">
-    <button
-     layout="topleft"
-     follows="left|top"
-     top_pad="9"
-     left="10"
-     visible="true"
-     height="23"
-     label="Connect..."
-     name="connect_btn"
-     width="251">
-      <commit_callback function="SocialSharing.Connect"/>
-    </button>
-
-    <button
-     layout="topleft"
-     follows="left|top|right"
-     top_delta="0"
-     left="10"
-     right="-10"
-     height="23"
-     label="Disconnect"
-     name="disconnect_btn"
-     width="210"
-     visible="false">
-      <commit_callback function="SocialSharing.Disconnect"/>
-    </button>
-    <text
-      layout="topleft"
-      length="1"
-      follows="top|left|right"
-      left="10"
-      right="-10"
-      height="16"
-      name="account_learn_more_label"
-      top_pad="5"
-      type="string">
-      [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Learn about posting to Facebook]
-    </text>
-  </panel>
-        
-       <text
-        length="1"
-        layout="topleft"
-        follows="top|left|right"
-        font="SansSerif"
-        height="16"
-        left="10"
-        name="status_caption_label"
-        top_pad="5"
-        type="string">
-        What's on your mind?
-       </text>
-       <text_editor
-        follows="left|top|right"
-        layout="topleft"
-        height="150"
-        width="252"
-        left="10"
-        length="1"
-        max_length="700"
-        name="status_message"
-        type="string"
-        word_wrap="true">
-       </text_editor>
-       <button
-        follows="left|top"
-        layout="topleft"
-        top_pad="6"
-        left="10"
-        height="23"
-        label="Post"
-        name="post_status_btn"
-        width="100">
-        <button.commit_callback
-          function="SocialSharing.SendStatus" />
-       </button>
-       <button
-        follows="right|top"
-        layout="topleft"
-        height="23"
-        label="Cancel"
-        name="cancel_status_btn"
-        right="-10"
-        top_delta="0"
-        width="100">
-        <button.commit_callback
-          function="SocialSharing.Cancel" />
-       </button>
-    </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
index 6074ab9ef6c4e0fe07e6500fef5de1c58e26883b..7fb2291423bd1e838870563872f1e80bfd049f39 100644
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -158,6 +158,7 @@
              length="1"
              max_length="700"
              name="photo_description"
+             spellcheck="true"
              type="string"
              word_wrap="true">
             </text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 26f54bacbccf516f2c5bd72103ae23d5dd63e5fd..e34335a2afcd2e7e696d3cee8805cfe3adfe4d0b 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -214,7 +214,7 @@ Hover your mouse over the options for more help.
          layout="topleft"
          left="10"
          name="group_mature_check"
-         tool_tip="Sets whether your group contains information rated as Moderate"
+         tool_tip="Maturity ratings designate the type of content and behavior allowed in a group"
          top_pad="4"
          width="190">
 			<combo_item name="select_mature" value="Select">
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 714d4166c05396c8696738394e02174dc6c1fdad..f15f79e9aaffbd42686d2fd774766e338891f4a8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -212,7 +212,15 @@ clicking on their names.
        layout="topleft"
        left="0"
        name="role_create"
-       width="120" />
+       width="100" />
+      <button
+       follows="top|left"
+       height="23"
+       label="Copy Role"
+       layout="topleft"
+       left_pad="10"
+       name="role_copy"
+       width="100" />
       <button
        height="23"
        follows="top|left"
@@ -220,7 +228,7 @@ clicking on their names.
        layout="topleft"
        left_pad="10"
        name="role_delete"
-       width="120" />
+       width="100" />
     </panel>
     <panel
      border="false"
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index fd6e96b9a7e1255972ac801a8fcfcabdeac0accd..13986c40308f5a505000e54d74296e77569f3a15 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -277,6 +277,7 @@
                  max_length="127"
                  name="notes_editor"
                  read_only="true"
+                 spellcheck="true"
                  text_readonly_color="white"
                  text_type="ascii_with_newline"
                  top_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 213f9a6b0cc2f85273ac4358ffa38f6928e941d9..726e7135956acfef98b084cb44d21e8b2d7a93e3 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -111,7 +111,6 @@
             combo_editor.font="SansSerifLarge"
             max_chars="128"
             top="0"
-            commit_on_focus_lost="false"
             combo_editor.prevalidate_callback="ascii"
             tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
             name="username_combo"
@@ -141,7 +140,7 @@
             follows="left|top"
             image_unselected="PushButton_Login"
             image_pressed="PushButton_Login_Pressed"
-            image_hover="PushButton_Login_Over"
+            image_hover_unselected="PushButton_Login_Over"
             label="Log In"
             label_color="White"
             font="SansSerifLarge"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 8fc0f6f642baf20cfa487b73df41d56127eab5e7..a47121ae995f848269bd4ae29c3c105aaaf4e33a 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -367,24 +367,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                          show_permissions_granted="true"
                          top="0"
                          width="307" />
-                </accordion_tab>
-              <accordion_tab
-               layout="topleft"
-               height="173"
-               name="tab_suggested_friends"
-               title="People you may want to friend">
-                <avatar_list
-                 ignore_online_status="true"
-                 allow_select="true"
-                 follows="all"
-                 height="173"
-                 layout="topleft"
-                 left="0"
-                 name="suggested_friends"
-                 show_permissions_granted="true"
-                 top="0"
-                 width="307" />
-              </accordion_tab>              
+                </accordion_tab>           
             </accordion>
             <text
              follows="all"
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
index 331a08b4bbf5cf4f85364e5b197c6b5d78a1bf2d..63c7259878687f5727a6bceb0d416430a7c1d155 100644
--- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
@@ -80,6 +80,7 @@
      left="5"
      max_length="700"
      name="msg_form"
+     spellcheck="true"
      right="-4"
      top_pad="5"
      word_wrap="true">
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 5d060c0a0dcdda1acedabc5dc56d491cf048477d..8243c2715df910b8ff89730a8bccd242c9eb07be 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -94,6 +94,7 @@
      layout="topleft"
      left_delta="0"
      name="texture_detail_0"
+     default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5"
      top_delta="20"
      width="100" />
     <texture_picker
@@ -102,6 +103,7 @@
      layout="topleft"
      left_pad="10"
      name="texture_detail_1"
+     default_image_id="63338ede-0037-c4fd-855b-015d77112fc8"
      top_delta="0"
      width="100" />
     <texture_picker
@@ -110,6 +112,7 @@
      layout="topleft"
      left_pad="10"
      name="texture_detail_2"
+     default_image_id="303cd381-8560-7579-23f1-f0a880799740"
      top_delta="0"
      width="100" />
     <texture_picker
@@ -118,6 +121,7 @@
      layout="topleft"
      left_pad="10"
      name="texture_detail_3"
+     default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c"
      top_delta="0"
      width="100" />
     <text
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index c56a5e17cdd53c46a2c7f7a3ca5009b2f59ed335..ed37e9e2ccdf8844e315518f90213eb73ad60768 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -28,10 +28,6 @@
     name="Title">
     Script: [NAME]
   </panel.string>
-  <panel.string
-    name="external_editor_not_set">
-    Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
-  </panel.string>
   <menu_bar
     bg_visible="false"
     follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 305cce1cbe722f7ecabd4cb4ed3be344dd98516a..981b9ab8816799776e4dc377a11272898fe6f109 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -56,23 +56,6 @@
     <button.commit_callback
      function="Snapshot.SaveToProfile" />
   </button>
-  <button
-   follows="left|top"
-   font="SansSerif"
-   halign="left"
-   height="22"
-   image_overlay="Snapshot_Facebook"
-   image_overlay_alignment="left"
-   image_top_pad="0"
-   imgoverlay_label_space="10"
-   label="Share to Facebook"
-   layout="topleft"
-   left_delta="0"
-   name="send_to_facebook_btn"
-   top_pad="5">
-    <button.commit_callback
-     function="Snapshot.SendToFacebook"/>
-  </button>
   <button
    follows="left|top"
    font="SansSerif"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index d86cb92981040bc1ad28386c9b31b2b3fcdcb976..2fdbee49f0389991f64fa5be59baf009550160b3 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
@@ -126,6 +126,7 @@
      length="1"
      max_length="700"
      name="caption"
+     spellcheck="true"
      width="200"
      top_pad="2"
      type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
index 9a460ceead7e6d9d09ca75413c824e7a682961ed..8774d09a03ea1e11a18bdfa896e3f58adf5ac30c 100644
--- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
@@ -39,6 +39,7 @@
            length="1"
            max_length="140"
            name="photo_status"
+           spellcheck="true"
            type="string"
            word_wrap="true">
           </text_editor>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 148effb01d9b42fd67322e0f6dab0d3a618e3627..c386cb94577370b93fa9aa7749406b3aa03c7918 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -57,6 +57,9 @@ Render quality: [RENDER_QUALITY]
 Advanced Lighting Model: [GPU_SHADERS]
 Texture memory: [TEXTURE_MEMORY]MB
 VFS (cache) creation time: [VFS_TIME]
+	</string>
+	<string name="AboutOSXHiDPI">
+HiDPI display mode: [HIDPI]
 	</string>
 	<string name="AboutLibs">
 J2C Decoder Version: [J2C_VERSION]
@@ -199,13 +202,7 @@ Please try logging in again in a minute.</string>
 	<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
 	<string name="TestingDisconnect">Testing viewer disconnect</string>
 
-	<!-- SLShare: Facebook, Flickr, and Twitter -->
-  <string name="SocialFacebookConnecting">Connecting to Facebook...</string>
-  <string name="SocialFacebookPosting">Posting...</string>
-  <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string>
-  <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string>
-  <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string>
-  <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string>
+	<!-- SLShare: Flickr and Twitter -->
   <string name="SocialFlickrConnecting">Connecting to Flickr...</string>
   <string name="SocialFlickrPosting">Posting...</string>
   <string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string>
@@ -2302,6 +2299,9 @@ For AI Character: Get the closest navigable point to the point provided.
 	<string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string>
 	<string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string>
 	<string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string>
+	<string name="InventoryPlayAnimationTooltip">Open window with Play options.</string>
+	<string name="InventoryPlayGestureTooltip">Execute selected gesture in-world.</string>
+	<string name="InventoryPlaySoundTooltip">Open window with Play options.</string>
 	<string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string>
 	<string name="InventoryOutboxNotMerchantTooltip"></string>
 	<string name="InventoryOutboxNotMerchant">
@@ -3653,9 +3653,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Drag items from inventory here
   </string>
 
-  <string name="facebook_post_success">
-    You posted to Facebook.
-  </string>
   <string name="flickr_post_success">
     You posted to Flickr.
   </string>
@@ -3943,7 +3940,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
   <string name="EmptyOutfitText">There are no items in this outfit</string>
 
  <!-- External editor status codes -->
- <string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string>
+ <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string>
  <string name="ExternalEditorNotFound">Cannot find the external editor you specified.
 Try enclosing path to the editor with double quotes.
 (e.g. "/path to my/editor" "%s")</string>
@@ -4088,7 +4085,6 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Conversations_Label">Conversations</string>
   <string name="Command_Compass_Label">Compass</string>
   <string name="Command_Destinations_Label">Destinations</string>
-  <string name="Command_Facebook_Label">Facebook</string>
   <string name="Command_Flickr_Label">Flickr</string>
   <string name="Command_Gestures_Label">Gestures</string>
   <string name="Command_Grid_Status_Label">Grid status</string>
@@ -4121,7 +4117,6 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Conversations_Tooltip">Converse with everyone</string>
   <string name="Command_Compass_Tooltip">Compass</string>
   <string name="Command_Destinations_Tooltip">Destinations of interest</string>
-  <string name="Command_Facebook_Tooltip">Post to Facebook</string>
   <string name="Command_Flickr_Tooltip">Upload to Flickr</string>
   <string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
   <string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/person_view.xml b/indra/newview/skins/default/xui/en/widgets/person_view.xml
index 46c1b7ff75f2807041d70325accc847198427ad7..bfe6941a8a8b96fbe25c961b25e9b8d384800bef 100644
--- a/indra/newview/skins/default/xui/en/widgets/person_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/person_view.xml
@@ -13,16 +13,6 @@
   text_pad_right="4"
   arrow_size="10"
   max_folder_item_overlap="2">
-    <facebook_icon
-      follows="left"
-      height="14"
-      image_name="Facebook_Icon"
-      left="5"
-      bottom="6"
-      name="facebook_icon"
-      tool_tip="Facebook User"
-      visible="false"
-      width="14" />
     <avatar_icon
       follows="left"
       layout="topleft"
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 3ac2cfb69b839d926e3bf9c88e1e3eff9595f6c7..4239c949fdc624e5d7257a3a3d9ed4bcd1f1c6d0 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2987,7 +2987,7 @@ Si vous restez dans cette région, vous serez déconnecté(e).
 Si vous restez dans cette région, vous serez déconnecté(e).
 	</notification>
 	<notification name="LoadWebPage">
-		Charger la page Web [URL] ?
+Charger la page Web [URL] ?
 
 [MESSAGE]