diff --git a/.hgtags b/.hgtags
index de85203089dac76ddabe601cc1bfc0bd77d79695..091e54ebf13b0f2c9b2e7b479bd05a36a2b5e299 100755
--- a/.hgtags
+++ b/.hgtags
@@ -534,3 +534,4 @@ abcab37e1b29414ab8c03af9ca2ab489d809788a 5.0.7-release
 ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
 26d9e9bb166a9a417f35b1863223a597af8185fd 5.1.1-release
 2eb917875efdfe920680b9049302d0f03721245d 5.1.2-release
+7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release
diff --git a/autobuild.xml b/autobuild.xml
index 399ecff57baf85fd2cbfae7e79d3df392da53b53..cea8b51ec5e4c6c8642e72ecf23da0968d20394e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -556,9 +556,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bbdea742f2a89bcd6360e61e01d6be93</string>
+              <string>118987b1a5b56214cfdbd0c763e180da</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8207/32592/dullahan-1.1.820_3.3071.1637.gcb6cf75-darwin64-508196.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15127/97748/dullahan-1.1.1080_3.3325.1750.gaabe4c4-darwin64-513449.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -568,9 +568,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>31e11a74e0d3f1e5e4036cb5fea8d944</string>
+              <string>2ecc71350b30a1057091b9cd7af18b1c</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8209/32599/dullahan-1.1.820_3.3071.1634.g9cc59c8-windows-508196.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15128/97755/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows-513449.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -580,16 +580,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f965d244e7921c06ee79b68a4abcea3b</string>
+              <string>2ed3e49388514dafb907c59a209d580e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8208/32602/dullahan-1.1.820_3.3071.1634.g9cc59c8-windows64-508196.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15129/97760/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows64-513449.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.1.820_3.3071.1634.g9cc59c8</string>
+        <string>1.1.1080_3.3325.1750.gaabe4c4</string>
       </map>
       <key>elfio</key>
       <map>
@@ -3316,9 +3316,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c5e6d9440e3a4a12102dd2bbb703963e</string>
+              <string>e5635e173c75dc0675b48ab5f5e4868b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/2225/4736/vlc_bin-2.2.4.502214-darwin64-502214.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12143/71451/vlc_bin-2.2.8.511703-darwin64-511703.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3340,9 +3340,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dc37f7cc77a62891bb9ae46c9e19f95e</string>
+              <string>add560654a53cb1c554044a4fac3c718</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1219/2834/vlc_bin-2.2.4.501207-windows-501207.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3352,16 +3352,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>148ee599afeba9794de14ca433389504</string>
+              <string>94bf04b49acc1e1bf2c06e2232f8a083</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1218/2829/vlc_bin-2.2.4.501207-windows64-501207.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>2.2.4.502214</string>
+        <string>2.2.8.511703</string>
       </map>
       <key>xmlrpc-epi</key>
       <map>
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 129efeb5295e220bce8ead273cd362c6ebc01ae3..5cc129a2677fffb80c5e27a67e07a63f733a26b3 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -29,7 +29,6 @@ include_directories(SYSTEM
 
 set(llplugin_SOURCE_FILES
     llpluginclassmedia.cpp
-    llplugincookiestore.cpp
     llplugininstance.cpp
     llpluginmessage.cpp
     llpluginmessagepipe.cpp
@@ -43,7 +42,6 @@ set(llplugin_HEADER_FILES
 
     llpluginclassmedia.h
     llpluginclassmediaowner.h
-    llplugincookiestore.h
     llplugininstance.h
     llpluginmessage.h
     llpluginmessageclasses.h
@@ -70,20 +68,3 @@ add_library (llplugin ${llplugin_SOURCE_FILES})
 
 add_subdirectory(slplugin)
 
-# Add tests
-if (LL_TESTS)
-    include(LLAddBuildTest)
-    # UNIT TESTS
-    SET(llplugin_TEST_SOURCE_FILES
-      llplugincookiestore.cpp
-      )
-
-    # llplugincookiestore has a dependency on curl, so we need to link the curl library into the test.
-    set_source_files_properties(
-      llplugincookiestore.cpp
-      PROPERTIES
-        LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES};${NGHTTP2_LIBRARIES}"
-      )
-
-    LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}")
-endif (LL_TESTS)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index f3fd4277ce4166c796463b80abacabe7fd3c5d9b..9d447b0f373e10772a7034bfd8b628c9ef0cb109 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -31,6 +31,9 @@
 
 #include "llpluginclassmedia.h"
 #include "llpluginmessageclasses.h"
+#include "llcontrol.h"
+
+extern LLControlGroup gSavedSettings;    
 
 static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
 
@@ -792,15 +795,22 @@ F64 LLPluginClassMedia::getCPUUsage()
 	return result;
 }
 
-void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
+void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
-	message.setValue("file", file);
 	if(mPlugin && mPlugin->isBlocked())
 	{
 		// If the plugin sent a blocking pick-file request, the response should unblock it.
 		message.setValueBoolean("blocking_response", true);
 	}
+
+	LLSD file_list = LLSD::emptyArray();
+	for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
+	{
+		file_list.append(LLSD::String(*in_iter));
+	}
+	message.setValueLLSD("file_list", file_list);
+
 	sendMessage(message);
 }
 
@@ -836,11 +846,17 @@ void LLPluginClassMedia::paste()
 	sendMessage(message);
 }
 
-void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies)
+void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
+										 const std::string &user_data_path_cookies,
+										 const std::string &user_data_path_cef_log)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
 	message.setValue("cache_path", user_data_path_cache);
 	message.setValue("cookies_path", user_data_path_cookies);
+	message.setValue("cef_log_file", user_data_path_cef_log);
+
+	bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
+	message.setValueBoolean("cef_verbose_log", cef_verbose_log);
 	sendMessage(message);
 }
 
@@ -1092,6 +1108,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 		}
 		else if(message_name == "pick_file")
 		{
+			mIsMultipleFilePick = message.getValueBoolean("multiple_files");
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
 		}
 		else if(message_name == "auth_request")
@@ -1153,7 +1170,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 		{
 			mClickURL = message.getValue("uri");
 			mClickTarget = message.getValue("target");
-			mClickUUID = message.getValue("uuid");
+
+			// need a link to have a UUID that identifies it to a system further
+			// upstream - plugin could make it but we have access to LLUUID here
+			// so why don't we use it
+			mClickUUID = LLUUID::generateNewID().asString();
+
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
 		}
 		else if(message_name == "click_nofollow")
@@ -1168,13 +1190,6 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			mStatusCode = message.getValueS32("status_code");
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
 		}
-		else if(message_name == "cookie_set")
-		{
-			if(mOwner)
-			{
-				mOwner->handleCookieSet(this, message.getValue("cookie"));
-			}
-		}
 		else if(message_name == "close_request")
 		{
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
@@ -1289,16 +1304,9 @@ void LLPluginClassMedia::clear_cookies()
 	sendMessage(message);
 }
 
-void LLPluginClassMedia::set_cookies(const std::string &cookies)
-{
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
-	message.setValue("cookies", cookies);
-	sendMessage(message);
-}
-
-void LLPluginClassMedia::enable_cookies(bool enable)
+void LLPluginClassMedia::cookies_enabled(bool enable)
 {
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
 	message.setValueBoolean("enable", enable);
 	sendMessage(message);
 }
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 3b0739d044ca7999783bb6d6516d9d3173312880..3b3075c6bde90ec2d546f243517525ac85d3dd74 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -176,7 +176,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	
 	F64 getCPUUsage();
 	
-	void sendPickFileResponse(const std::string &file);
+	void sendPickFileResponse(const std::vector<std::string> files);
 
 	void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
 
@@ -195,7 +195,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	bool	canPaste() const { return mCanPaste; };
 	
 	// These can be called before init(), and they will be queued and sent before the media init message.
-	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies);
+	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
 	void	setLanguageCode(const std::string &language_code);
 	void	setPluginsEnabled(const bool enabled);
 	void	setJavascriptEnabled(const bool enabled);
@@ -210,7 +210,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void clear_cache();
 	void clear_cookies();
 	void set_cookies(const std::string &cookies);
-	void enable_cookies(bool enable);
+	void cookies_enabled(bool enable);
 	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
 	void browse_stop();
 	void browse_reload(bool ignore_cache = false);
@@ -277,6 +277,9 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	std::string	getAuthURL() const { return mAuthURL; };
 	std::string	getAuthRealm() const { return mAuthRealm; };
 
+	// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST
+	bool getIsMultipleFilePick() const { return mIsMultipleFilePick; }
+
 	// These are valid during MEDIA_EVENT_LINK_HOVERED
 	std::string	getHoverText() const { return mHoverText; };
 	std::string	getHoverLink() const { return mHoverLink; };
@@ -435,6 +438,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	std::string		mHoverText;
 	std::string		mHoverLink;
 	std::string     mFileDownloadFilename;
+	bool			mIsMultipleFilePick;
 	
 	/////////////////////////////////////////
 	// media_time class
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index 391c23d883c327e0e412773f47bdb6b7e991f9e6..89f55eaf716ac42b2ec0dc54cf1fb151a08e80a9 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file llpluginclassmediaowner.h
  * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
  *
@@ -6,21 +6,21 @@
  * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, 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$
  * @endcond
@@ -34,18 +34,17 @@
 #include <queue>
 
 class LLPluginClassMedia;
-class LLPluginCookieStore;
 
 class LLPluginClassMediaOwner
 {
 public:
 	typedef enum
 	{
-		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated 
+		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated
 		MEDIA_EVENT_TIME_DURATION_UPDATED,	// current time and/or duration have updated
 		MEDIA_EVENT_SIZE_CHANGED,			// media size has changed
 		MEDIA_EVENT_CURSOR_CHANGED,			// plugin has requested a cursor change
-		
+
 		MEDIA_EVENT_NAVIGATE_BEGIN,			// browser has begun navigation
 		MEDIA_EVENT_NAVIGATE_COMPLETE,		// browser has finished navigation
 		MEDIA_EVENT_PROGRESS_UPDATED,		// browser has updated loading progress
@@ -58,8 +57,8 @@ class LLPluginClassMediaOwner
 		MEDIA_EVENT_CLOSE_REQUEST,			// The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
 		MEDIA_EVENT_PICK_FILE_REQUEST,		// The plugin wants the user to pick a file
 		MEDIA_EVENT_GEOMETRY_CHANGE,		// The plugin requested its window geometry be changed (per the javascript window interface)
-	
-		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch 
+
+		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch
 		MEDIA_EVENT_PLUGIN_FAILED,			// The plugin died unexpectedly
 
 		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog
@@ -69,9 +68,9 @@ class LLPluginClassMediaOwner
 		MEDIA_EVENT_DEBUG_MESSAGE,			// plugin sending back debug information for host to process
 
 		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin
-		
+
 	} EMediaEvent;
-	
+
 	typedef enum
 	{
 		MEDIA_NONE,			// Uninitialized -- no useful state
@@ -81,12 +80,11 @@ class LLPluginClassMediaOwner
 		MEDIA_PLAYING,		// playing (only for time-based media)
 		MEDIA_PAUSED,		// paused (only for time-based media)
 		MEDIA_DONE			// finished playing (only for time-based media)
-	
+
 	} EMediaStatus;
-	
+
 	virtual ~LLPluginClassMediaOwner() {};
 	virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
-	virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};
 };
 
 #endif // LL_LLPLUGINCLASSMEDIAOWNER_H
diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp
deleted file mode 100644
index a5d717389d52a9484ff68cb55bd5646e30c670bc..0000000000000000000000000000000000000000
--- a/indra/llplugin/llplugincookiestore.cpp
+++ /dev/null
@@ -1,689 +0,0 @@
-/** 
- * @file llplugincookiestore.cpp
- * @brief LLPluginCookieStore provides central storage for http cookies used by plugins
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- * @endcond
- */
-
-#include "linden_common.h"
-#include "llstl.h"
-#include "indra_constants.h"
-
-#include "llplugincookiestore.h"
-#include <iostream>
-
-// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
-#include <curl/curl.h>
-
-LLPluginCookieStore::LLPluginCookieStore():
-	mHasChangedCookies(false)
-{
-}
-
-
-LLPluginCookieStore::~LLPluginCookieStore()
-{
-	clearCookies();
-}
-
-
-LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end):
-	mCookie(s, cookie_start, cookie_end - cookie_start),
-	mNameStart(0), mNameEnd(0),
-	mValueStart(0), mValueEnd(0),
-	mDomainStart(0), mDomainEnd(0),
-	mPathStart(0), mPathEnd(0),
-	mDead(false), mChanged(true)
-{
-}
-
-LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, const std::string &host)
-{
-	Cookie *result = new Cookie(s, cookie_start, cookie_end);
-
-	if(!result->parse(host))
-	{
-		delete result;
-		result = NULL;
-	}
-	
-	return result;
-}
-
-std::string LLPluginCookieStore::Cookie::getKey() const
-{
-	std::string result;
-	if(mDomainEnd > mDomainStart)
-	{
-		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
-	}
-	result += ';';
-	if(mPathEnd > mPathStart)
-	{
-		result += mCookie.substr(mPathStart, mPathEnd - mPathStart);
-	}
-	result += ';';
-	result += mCookie.substr(mNameStart, mNameEnd - mNameStart);
-	return result;
-}
-
-std::string LLPluginCookieStore::Cookie::getDomain() const
-{
-	std::string result;
-	if(mDomainEnd > mDomainStart)
-	{
-		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
-	}
-	return result;
-}
-
-bool LLPluginCookieStore::Cookie::parse(const std::string &host)
-{
-	bool first_field = true;
-
-	std::string::size_type cookie_end = mCookie.size();
-	std::string::size_type field_start = 0;
-
-	LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL;
-	while(field_start < cookie_end)
-	{
-		// Finding the start of the next field requires honoring special quoting rules
-		// see the definition of 'quoted-string' in rfc2616 for details
-		std::string::size_type next_field_start = findFieldEnd(field_start);
-
-		// The end of this field should not include the terminating ';' or any trailing whitespace
-		std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start);
-		if(field_end == std::string::npos || field_end < field_start)
-		{
-			// This field was empty or all whitespace.  Set end = start so it shows as empty.
-			field_end = field_start;
-		}
-		else if (field_end < next_field_start)
-		{
-			// we actually want the index of the char _after_ what 'last not of' found
-			++field_end;
-		}
-		
-		// find the start of the actual name (skip separator and possible whitespace)
-		std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start);
-		if(name_start == std::string::npos || name_start > next_field_start)
-		{
-			// Again, nothing but whitespace.
-			name_start = field_start;
-		}
-		
-		// the name and value are separated by the first equals sign
-		std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start);
-		if(name_value_sep == std::string::npos || name_value_sep > field_end)
-		{
-			// No separator found, so this is a field without an = 
-			name_value_sep = field_end;
-		}
-		
-		// the name end is before the name-value separator
-		std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep);
-		if(name_end == std::string::npos || name_end < name_start)
-		{
-			// I'm not sure how we'd hit this case... it seems like it would have to be an empty name.
-			name_end = name_start;
-		}
-		else if (name_end < name_value_sep)
-		{
-			// we actually want the index of the char _after_ what 'last not of' found
-			++name_end;
-		}
-		
-		// Value is between the name-value sep and the end of the field.
-		std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep);
-		if(value_start == std::string::npos || value_start > field_end)
-		{
-			// All whitespace or empty value
-			value_start = field_end;
-		}
-		std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end);
-		if(value_end == std::string::npos || value_end < value_start)
-		{
-			// All whitespace or empty value
-			value_end = value_start;
-		}
-		else if (value_end < field_end)
-		{
-			// we actually want the index of the char _after_ what 'last not of' found
-			++value_end;
-		}
-
-		LL_DEBUGS("CookieStoreParse") 
-			<< "    field name: \"" << mCookie.substr(name_start, name_end - name_start) 
-			<< "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\""
-			<< LL_ENDL;
-				
-		// See whether this field is one we know
-		if(first_field)
-		{
-			// The first field is the name=value pair
-			mNameStart = name_start;
-			mNameEnd = name_end;
-			mValueStart = value_start;
-			mValueEnd = value_end;
-			first_field = false;
-		}
-		else
-		{
-			// Subsequent fields must come from the set in rfc2109
-			if(matchName(name_start, name_end, "expires"))
-			{
-				std::string date_string(mCookie, value_start, value_end - value_start); 
-				// If the cookie contains an "expires" field, it MUST contain a parsable date.
-				
-				// HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one.
-				//  The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate.
-#if 1
-				time_t date = curl_getdate(date_string.c_str(), NULL );
-				mDate.secondsSinceEpoch((F64)date);
-				LL_DEBUGS("CookieStoreParse") << "        expire date parsed to: " << mDate.asRFC1123() << LL_ENDL;
-#else
-				// This doesn't work (rfc1123-format dates cause it to fail)
-				if(!mDate.fromString(date_string))
-				{
-					// Date failed to parse.
-					LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL;
-					return false;
-				}
-#endif
-			}
-			else if(matchName(name_start, name_end, "domain"))
-			{
-				mDomainStart = value_start;
-				mDomainEnd = value_end;
-			}
-			else if(matchName(name_start, name_end, "path"))
-			{
-				mPathStart = value_start;
-				mPathEnd = value_end;
-			}
-			else if(matchName(name_start, name_end, "max-age"))
-			{
-				// TODO: how should we handle this?
-			}
-			else if(matchName(name_start, name_end, "secure"))
-			{
-				// We don't care about the value of this field (yet)
-			}
-			else if(matchName(name_start, name_end, "version"))
-			{
-				// We don't care about the value of this field (yet)
-			}
-			else if(matchName(name_start, name_end, "comment"))
-			{
-				// We don't care about the value of this field (yet)
-			}
-			else if(matchName(name_start, name_end, "httponly"))
-			{
-				// We don't care about the value of this field (yet)
-			}
-			else
-			{
-				// An unknown field is a parse failure
-				LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL;
-				return false;
-			}
-			
-		}
-
-		
-		// move on to the next field, skipping this field's separator and any leading whitespace
-		field_start = mCookie.find_first_not_of("; ", next_field_start);
-	}
-		
-	// The cookie MUST have a name
-	if(mNameEnd <= mNameStart)
-		return false;
-	
-	// If the cookie doesn't have a domain, add the current host as the domain.
-	if(mDomainEnd <= mDomainStart)
-	{
-		if(host.empty())
-		{
-			// no domain and no current host -- this is a parse failure.
-			return false;
-		}
-		
-		// Figure out whether this cookie ended with a ";" or not...
-		std::string::size_type last_char = mCookie.find_last_not_of(" ");
-		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
-		{
-			mCookie += ";";
-		}
-		
-		mCookie += " domain=";
-		mDomainStart = mCookie.size();
-		mCookie += host;
-		mDomainEnd = mCookie.size();
-		
-		LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL;
-	}
-
-	// If the cookie doesn't have a path, add "/".
-	if(mPathEnd <= mPathStart)
-	{
-		// Figure out whether this cookie ended with a ";" or not...
-		std::string::size_type last_char = mCookie.find_last_not_of(" ");
-		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
-		{
-			mCookie += ";";
-		}
-		
-		mCookie += " path=";
-		mPathStart = mCookie.size();
-		mCookie += "/";
-		mPathEnd = mCookie.size();
-		
-		LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL;
-	}
-	
-	
-	return true;
-}
-
-std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end)
-{
-	std::string::size_type result = start;
-	
-	if(end == std::string::npos)
-		end = mCookie.size();
-	
-	bool in_quotes = false;
-	for(; (result < end); result++)
-	{
-		switch(mCookie[result])
-		{
-			case '\\':
-				if(in_quotes)
-					result++; // The next character is backslash-quoted.  Skip over it.
-			break;
-			case '"':
-				in_quotes = !in_quotes;
-			break;
-			case ';':
-				if(!in_quotes)
-					return result;
-			break;
-		}		
-	}
-	
-	// If we got here, no ';' was found.
-	return end;
-}
-
-bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name)
-{
-	// NOTE: this assumes 'name' is already in lowercase.  The code which uses it should be able to arrange this...
-	
-	while((start < end) && (*name != '\0'))
-	{
-		if(tolower(mCookie[start]) != *name)
-			return false;
-			
-		start++;
-		name++;
-	}
-	
-	// iff both strings hit the end at the same time, they're equal.
-	return ((start == end) && (*name == '\0'));
-}
-
-std::string LLPluginCookieStore::getAllCookies()
-{
-	std::stringstream result;
-	writeAllCookies(result);
-	return result.str();
-}
-
-void LLPluginCookieStore::writeAllCookies(std::ostream& s)
-{
-	cookie_map_t::iterator iter;
-	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
-	{
-		// Don't return expired cookies
-		if(!iter->second->isDead())
-		{
-			s << (iter->second->getCookie()) << "\n";
-		}
-	}
-
-}
-
-std::string LLPluginCookieStore::getPersistentCookies()
-{
-	std::stringstream result;
-	writePersistentCookies(result);
-	return result.str();
-}
-
-void LLPluginCookieStore::writePersistentCookies(std::ostream& s)
-{
-	cookie_map_t::iterator iter;
-	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
-	{
-		// Don't return expired cookies or session cookies
-		if(!iter->second->isDead() && !iter->second->isSessionCookie())
-		{
-			s << iter->second->getCookie() << "\n";
-		}
-	}
-}
-
-std::string LLPluginCookieStore::getChangedCookies(bool clear_changed)
-{
-	std::stringstream result;
-	writeChangedCookies(result, clear_changed);
-	
-	return result.str();
-}
-
-void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed)
-{
-	if(mHasChangedCookies)
-	{
-		LL_DEBUGS() << "returning changed cookies: " << LL_ENDL;
-		cookie_map_t::iterator iter;
-		for(iter = mCookies.begin(); iter != mCookies.end(); )
-		{
-			cookie_map_t::iterator next = iter;
-			next++;
-			
-			// Only return cookies marked as "changed"
-			if(iter->second->isChanged())
-			{
-				s << iter->second->getCookie() << "\n";
-
-				LL_DEBUGS() << "    " << iter->second->getCookie() << LL_ENDL;
-
-				// If requested, clear the changed mark
-				if(clear_changed)
-				{
-					if(iter->second->isDead())
-					{
-						// If this cookie was previously marked dead, it needs to be removed entirely.	
-						delete iter->second;
-						mCookies.erase(iter);
-					}
-					else
-					{
-						// Not dead, just mark as not changed.
-						iter->second->setChanged(false);
-					}
-				}
-			}
-			
-			iter = next;
-		}
-	}
-	
-	if(clear_changed)
-		mHasChangedCookies = false;
-}
-
-void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed)
-{
-	clearCookies();
-	setCookies(cookies, mark_changed);
-}
-
-void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed)
-{
-	clearCookies();
-	readCookies(s, mark_changed);
-}
-	
-void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed)
-{
-	std::string::size_type start = 0;
-
-	while(start != std::string::npos)
-	{
-		std::string::size_type end = cookies.find_first_of("\r\n", start);
-		if(end > start)
-		{
-			// The line is non-empty.  Try to create a cookie from it.
-			setOneCookie(cookies, start, end, mark_changed);
-		}
-		start = cookies.find_first_not_of("\r\n ", end);
-	}
-}
-
-void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed)
-{
-	std::string::size_type start = 0;
-
-	while(start != std::string::npos)
-	{
-		std::string::size_type end = cookies.find_first_of("\r\n", start);
-		if(end > start)
-		{
-			// The line is non-empty.  Try to create a cookie from it.
-			setOneCookie(cookies, start, end, mark_changed, host);
-		}
-		start = cookies.find_first_not_of("\r\n ", end);
-	}
-}
-			
-void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed)
-{
-	std::string line;
-	while(s.good() && !s.eof())
-	{
-		std::getline(s, line);
-		if(!line.empty())
-		{
-			// Try to create a cookie from this line.
-			setOneCookie(line, 0, std::string::npos, mark_changed);
-		}
-	}
-}
-
-std::string LLPluginCookieStore::quoteString(const std::string &s)
-{
-	std::stringstream result;
-	
-	result << '"';
-	
-	for(std::string::size_type i = 0; i < s.size(); ++i)
-	{
-		char c = s[i];
-		switch(c)
-		{
-			// All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616:
-			case '(': case ')': case '<': case '>': case '@':
-			case ',': case ';': case ':': case '\\': case '"':
-			case '/': case '[': case ']': case '?': case '=':
-			case '{': case '}':	case ' ': case '\t':
-				result << '\\';
-			break;
-		}
-		
-		result << c;
-	}
-	
-	result << '"';
-	
-	return result.str();
-}
-
-std::string LLPluginCookieStore::unquoteString(const std::string &s)
-{
-	std::stringstream result;
-	
-	bool in_quotes = false;
-	
-	for(std::string::size_type i = 0; i < s.size(); ++i)
-	{
-		char c = s[i];
-		switch(c)
-		{
-			case '\\':
-				if(in_quotes)
-				{
-					// The next character is backslash-quoted.  Pass it through untouched.
-					++i; 
-					if(i < s.size())
-					{
-						result << s[i];
-					}
-					continue;
-				}
-			break;
-			case '"':
-				in_quotes = !in_quotes;
-				continue;
-			break;
-		}
-		
-		result << c;
-	}
-	
-	return result.str();
-}
-
-// The flow for deleting a cookie is non-obvious enough that I should call it out here...
-// Deleting a cookie is done by setting a cookie with the same name, path, and domain, but with an expire timestamp in the past.
-// (This is exactly how a web server tells a browser to delete a cookie.)
-// When deleting with mark_changed set to true, this replaces the existing cookie in the list with an entry that's marked both dead and changed.
-// Some time later when writeChangedCookies() is called with clear_changed set to true, the dead cookie is deleted from the list after being returned, so that the
-// delete operation (in the form of the expired cookie) is passed along.
-void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host)
-{
-	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host);
-	if(cookie)
-	{
-		LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL;
-		
-		// Create a key for this cookie
-		std::string key = cookie->getKey();
-		
-		// Check to see whether this cookie should have expired
-		if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now()))
-		{
-			// This cookie has expired.
-			if(mark_changed)
-			{
-				// If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas.
-				cookie->setDead(true);
-				LL_DEBUGS("CookieStoreUpdate") << "    marking dead" << LL_ENDL;
-			}
-			else
-			{
-				// If we're not marking cookies as changed, we don't need to keep this cookie at all.
-				// If the cookie was already in the list, delete it.
-				removeCookie(key);
-
-				delete cookie;
-				cookie = NULL;
-
-				LL_DEBUGS("CookieStoreUpdate") << "    removing" << LL_ENDL;
-			}
-		}
-		
-		if(cookie)
-		{
-			// If it already exists in the map, replace it.
-			cookie_map_t::iterator iter = mCookies.find(key);
-			if(iter != mCookies.end())
-			{
-				if(iter->second->getCookie() == cookie->getCookie())
-				{
-					// The new cookie is identical to the old -- don't mark as changed.
-					// Just leave the old one in the map.
-					delete cookie;
-					cookie = NULL;
-
-					LL_DEBUGS("CookieStoreUpdate") << "    unchanged" << LL_ENDL;
-				}
-				else
-				{
-					// A matching cookie was already in the map.  Replace it.
-					delete iter->second;
-					iter->second = cookie;
-					
-					cookie->setChanged(mark_changed);
-					if(mark_changed)
-						mHasChangedCookies = true;
-
-					LL_DEBUGS("CookieStoreUpdate") << "    replacing" << LL_ENDL;
-				}
-			}
-			else
-			{
-				// The cookie wasn't in the map.  Insert it.
-				mCookies.insert(std::make_pair(key, cookie));
-				
-				cookie->setChanged(mark_changed);
-				if(mark_changed)
-					mHasChangedCookies = true;
-
-				LL_DEBUGS("CookieStoreUpdate") << "    adding" << LL_ENDL;
-			}
-		}
-	}
-	else
-	{
-		LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL;
-	}
-
-}
-
-void LLPluginCookieStore::clearCookies()
-{
-	std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer());
-	mCookies.clear();
-}
-
-void LLPluginCookieStore::removeCookie(const std::string &key)
-{
-	cookie_map_t::iterator iter = mCookies.find(key);
-	if(iter != mCookies.end())
-	{
-		delete iter->second;
-		mCookies.erase(iter);
-	}
-}
-
-void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
-{
-	cookie_map_t::iterator iter = mCookies.begin();
-	while(iter != mCookies.end())
-	{ 
-		if(iter->second->getDomain() == domain)
-		{
-            cookie_map_t::iterator doErase = iter;
-            iter++;
-			delete doErase->second;
-			mCookies.erase(doErase);
-		}
-        else
-        {
-            iter++;
-        }
-	}
-}
diff --git a/indra/llplugin/llplugincookiestore.h b/indra/llplugin/llplugincookiestore.h
deleted file mode 100644
index a2fdeab64754a45a68f07570a66ebd0070cd03e2..0000000000000000000000000000000000000000
--- a/indra/llplugin/llplugincookiestore.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/** 
- * @file llplugincookiestore.h
- * @brief LLPluginCookieStore provides central storage for http cookies used by plugins
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- * @endcond
- */
-
-#ifndef LL_LLPLUGINCOOKIESTORE_H
-#define LL_LLPLUGINCOOKIESTORE_H
-
-#include "lldate.h"
-#include <map>
-#include <string>
-#include <iostream>
-
-class LLPluginCookieStore
-{
-	LOG_CLASS(LLPluginCookieStore);
-public:
-	LLPluginCookieStore();
-	~LLPluginCookieStore();
-
-	// gets all cookies currently in storage -- use when initializing a plugin
-	std::string getAllCookies();
-	void writeAllCookies(std::ostream& s);
-	
-	// gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file
-	std::string getPersistentCookies();
-	void writePersistentCookies(std::ostream& s);
-	
-	// gets cookies which are marked as "changed" -- use when sending periodic updates to plugins
-	std::string getChangedCookies(bool clear_changed = true);
-	void writeChangedCookies(std::ostream& s, bool clear_changed = true);
-	
-	// (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file
-	void setAllCookies(const std::string &cookies, bool mark_changed = false);
-	void readAllCookies(std::istream& s, bool mark_changed = false);
-	
-	// sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin
-	void setCookies(const std::string &cookies, bool mark_changed = true);
-	void readCookies(std::istream& s, bool mark_changed = true);
-
-	// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually
-	void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true);
-
-	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
-	static std::string quoteString(const std::string &s);
-	static std::string unquoteString(const std::string &s);
-
-	void removeCookiesByDomain(const std::string &domain);
-	
-private:
-
-	void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host = LLStringUtil::null);
-
-	class Cookie
-	{
-	public:
-		static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos, const std::string &host = LLStringUtil::null);
-		
-		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
-		std::string getKey() const;
-		std::string getDomain() const;
-		
-		const std::string &getCookie() const { return mCookie; };
-		bool isSessionCookie() const { return mDate.isNull(); };
-
-		bool isDead() const { return mDead; };
-		void setDead(bool dead) { mDead = dead; };
-		
-		bool isChanged() const { return mChanged; };
-		void setChanged(bool changed) { mChanged = changed; };
-
-		const LLDate &getDate() const { return mDate; };
-		
-	private:
-		Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos);
-		bool parse(const std::string &host);
-		std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos);
-		bool matchName(std::string::size_type start, std::string::size_type end, const char *name);
-		
-		std::string mCookie;	// The full cookie, in RFC 2109 string format
-		LLDate mDate;			// The expiration date of the cookie.  For session cookies, this will be a null date (mDate.isNull() is true).
-		// Start/end indices of various parts of the cookie string.  Stored as indices into the string to save space and time.
-		std::string::size_type mNameStart, mNameEnd;
-		std::string::size_type mValueStart, mValueEnd;
-		std::string::size_type mDomainStart, mDomainEnd;
-		std::string::size_type mPathStart, mPathEnd;
-		bool mDead;
-		bool mChanged;
-	};
-	
-	typedef std::map<std::string, Cookie*> cookie_map_t;
-	
-	cookie_map_t mCookies;
-	bool mHasChangedCookies;
-	
-	void clearCookies();
-	void removeCookie(const std::string &key);
-};
-
-#endif // LL_LLPLUGINCOOKIESTORE_H
diff --git a/indra/llplugin/tests/llplugincookiestore_test.cpp b/indra/llplugin/tests/llplugincookiestore_test.cpp
deleted file mode 100644
index c2cb236cbabebcf0845f35def9a4b5e13caa80fb..0000000000000000000000000000000000000000
--- a/indra/llplugin/tests/llplugincookiestore_test.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/** 
- * @file llplugincookiestore_test.cpp
- * @brief Unit tests for LLPluginCookieStore.
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- * @endcond
- */
-
-#include "linden_common.h"
-#include <list>
-#include "../test/lltut.h"
-
-#include "../llplugincookiestore.h"
-
-
-namespace tut
-{
-	// Main Setup
-	struct LLPluginCookieStoreFixture
-	{
-		LLPluginCookieStoreFixture()
-		{
-			// We need dates definitively in the past and the future to properly test cookie expiration.
-			LLDate now = LLDate::now(); 
-			LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0));	// 1 day in the past
-			LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0));	// 1 day in the future
-			
-			mPastString = past.asRFC1123();
-			mFutureString = future.asRFC1123();
-		}
-		
-		std::string mPastString;
-		std::string mFutureString;
-		LLPluginCookieStore mCookieStore;
-		
-		// List of cookies used for validation
-		std::list<std::string> mCookies;
-		
-		// This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore
-		void setCookies(const std::string &cookies)
-		{
-			mCookies.clear();
-			std::string::size_type start = 0;
-
-			while(start != std::string::npos)
-			{
-				std::string::size_type end = cookies.find_first_of("\r\n", start);
-				if(end > start)
-				{
-					std::string line(cookies, start, end - start);
-					if(line.find_first_not_of("\r\n\t ") != std::string::npos)
-					{
-						// The line has some non-whitespace characters.  Save it to the list.
-						mCookies.push_back(std::string(cookies, start, end - start));
-					}
-				}
-				start = cookies.find_first_not_of("\r\n ", end);
-			}
-		}
-		
-		// This ensures that a cookie matching the one passed is in the list.
-		void ensureCookie(const std::string &cookie)
-		{
-			std::list<std::string>::iterator iter;
-			for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
-			{
-				if(*iter == cookie)
-				{
-					// Found the cookie
-					// TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare.
-					return;
-				}
-			}
-			
-			// Didn't find this cookie
-			std::string message = "cookie not found: ";
-			message += cookie;
-			ensure(message, false);
-		}
-		
-		// This ensures that the number of cookies in the list matches what's expected.
-		void ensureSize(const std::string &message, size_t size)
-		{
-			if(mCookies.size() != size)
-			{
-				std::stringstream full_message;
-				
-				full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")";
-				ensure(full_message.str(), false);
-			}
-		}
-	};
-	
-	typedef test_group<LLPluginCookieStoreFixture> factory;
-	typedef factory::object object;
-	factory tf("LLPluginCookieStore");
-
-	// Tests
-	template<> template<>
-	void object::test<1>()
-	{
-		// Test 1: cookie uniqueness and update lists.
-		// Valid, distinct cookies:
-		
-		std::string cookie01 = "cookieA=value; domain=example.com; path=/";
-		std::string cookie02 = "cookieB=value; Domain=example.com; Path=/; Max-Age=10; Secure; Version=1; Comment=foo!; HTTPOnly"; // cookie with every supported field, in different cases.
-		std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain
-		std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path
-		std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value
-		std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie
-		cookie06 += mFutureString;
-		
-		mCookieStore.setCookies(cookie01);
-		mCookieStore.setCookies(cookie02);
-		mCookieStore.setCookies(cookie03);
-		mCookieStore.setCookies(cookie04);
-		mCookieStore.setCookies(cookie05);
-		mCookieStore.setCookies(cookie06);
-		
-		// Invalid cookies (these will get parse errors and not be added to the store)
-
-		std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name
-		std::string badcookie02 = "cookieE=value; path=/"; // no domain
-
-		mCookieStore.setCookies(badcookie01);
-		mCookieStore.setCookies(badcookie02);
-		
-		// All cookies added so far should have been marked as "changed"
-		setCookies(mCookieStore.getChangedCookies());
-		ensureSize("count of changed cookies", 6);
-		ensureCookie(cookie01);
-		ensureCookie(cookie02);
-		ensureCookie(cookie03);
-		ensureCookie(cookie04);
-		ensureCookie(cookie05);
-		ensureCookie(cookie06);
-		
-		// Save off the current state of the cookie store (we'll restore it later)
-		std::string savedCookies = mCookieStore.getAllCookies();
-		
-		// Test replacing cookies
-		std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/";	// updated value
-		std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past)
-		cookie02a += mPastString;
-		
-		mCookieStore.setCookies(cookie01a);
-		mCookieStore.setCookies(cookie02a);
-
-		// test for getting changed cookies
-		setCookies(mCookieStore.getChangedCookies());
-		ensureSize("count of updated cookies", 2);
-		ensureCookie(cookie01a);
-		ensureCookie(cookie02a);
-		
-		// and for the state of the store after getting changed cookies
-		setCookies(mCookieStore.getAllCookies());
-		ensureSize("count of valid cookies", 5);
-		ensureCookie(cookie01a);
-		ensureCookie(cookie03);
-		ensureCookie(cookie04);
-		ensureCookie(cookie05);
-		ensureCookie(cookie06);
-
-		// Check that only the persistent cookie is returned here
-		setCookies(mCookieStore.getPersistentCookies());
-		ensureSize("count of persistent cookies", 1);
-		ensureCookie(cookie06);
-
-		// Restore the cookie store to a previous state and verify
-		mCookieStore.setAllCookies(savedCookies);
-		
-		// Since setAllCookies defaults to not marking cookies as changed, this list should be empty.
-		setCookies(mCookieStore.getChangedCookies());
-		ensureSize("count of changed cookies after restore", 0);
-
-		// Verify that the restore worked as it should have.
-		setCookies(mCookieStore.getAllCookies());
-		ensureSize("count of restored cookies", 6);
-		ensureCookie(cookie01);
-		ensureCookie(cookie02);
-		ensureCookie(cookie03);
-		ensureCookie(cookie04);
-		ensureCookie(cookie05);
-		ensureCookie(cookie06);
-	}
-
-}
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 18810f5794c331a8262f9f3a9e6414dc6d8d6b9a..2bd5526a860bf60c7758d49bed2fb6b5fcf76c65 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -38,6 +38,7 @@
 #include "media_plugin_base.h"
 
 #include <functional>
+#include <chrono>
 
 #include "dullahan.h"
 
@@ -64,12 +65,12 @@ class MediaPluginCEF :
 	void onLoadStartCallback();
 	void onRequestExitCallback();
 	void onLoadEndCallback(int httpStatusCode);
+	void onLoadError(int status, const std::string error_text);
 	void onAddressChangeCallback(std::string url);
-	void onNavigateURLCallback(std::string url, std::string target);
+	void onOpenPopupCallback(std::string url, std::string target);
 	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
 	void onCursorChangedCallback(dullahan::ECursorType type);
-	void onFileDownloadCallback(std::string filename);
-	const std::string onFileDialogCallback();
+	const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);
 
 	void postDebugMessage(const std::string& msg);
 	void authResponse(LLPluginMessage &message);
@@ -95,7 +96,9 @@ class MediaPluginCEF :
 	bool mCanPaste;
 	std::string mCachePath;
 	std::string mCookiePath;
-	std::string mPickedFile;
+	std::string mCefLogFile;
+	bool mCefLogVerbose;
+	std::vector<std::string> mPickedFiles;
 	VolumeCatcher mVolumeCatcher;
 	F32 mCurVolume;
 	dullahan* mCEFLib;
@@ -115,7 +118,7 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCookiesEnabled = true;
 	mPluginsEnabled = false;
 	mJavascriptEnabled = true;
-	mDisableGPU = true;
+	mDisableGPU = false;
 	mUserAgentSubtring = "";
 	mAuthUsername = "";
 	mAuthPassword = "";
@@ -125,7 +128,9 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCanPaste = false;
 	mCachePath = "";
 	mCookiePath = "";
-	mPickedFile = "";
+	mCefLogFile = "";
+	mCefLogVerbose = false;
+	mPickedFiles.clear();
 	mCurVolume = 0.0;
 
 	mCEFLib = new dullahan();
@@ -166,6 +171,10 @@ void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, i
 		{
 			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
 		}
+		else
+		{
+			mCEFLib->setSize(mWidth, mHeight);
+		}
 		setDirty(0, 0, mWidth, mHeight);
 	}
 }
@@ -210,6 +219,21 @@ void MediaPluginCEF::onLoadStartCallback()
 	sendMessage(message);
 }
 
+/////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onLoadError(int status, const std::string error_text)
+{
+	std::stringstream msg;
+
+	msg << "<b>Loading error!</b>";
+	msg << "<p>";
+	msg << "Message: " << error_text;
+	msg << "<br>";
+	msg << "Code: " << status;
+
+	mCEFLib->showBrowserMessage(msg.str());
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginCEF::onRequestExitCallback()
@@ -243,12 +267,11 @@ void MediaPluginCEF::onAddressChangeCallback(std::string url)
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
+void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
 	message.setValue("uri", url);
 	message.setValue("target", target);
-	message.setValue("uuid", "");	// not used right now
 	sendMessage(message);
 }
 
@@ -287,30 +310,52 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
+const std::vector<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, std::string dialog_accept_filter, bool& use_default)
 {
-	mAuthOK = false;
+	// do not use the default CEF file picker
+	use_default = false;
 
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
-	message.setValue("filename", filename);
+	if (dialog_type == dullahan::FD_OPEN_FILE)
+	{
+		mPickedFiles.clear();
 
-	sendMessage(message);
-}
+		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
+		message.setValueBoolean("blocking_request", true);
+		message.setValueBoolean("multiple_files", false);
 
-////////////////////////////////////////////////////////////////////////////////
-//
-const std::string MediaPluginCEF::onFileDialogCallback()
-{
-	mPickedFile.clear();
+		sendMessage(message);
 
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
-	message.setValueBoolean("blocking_request", true);
+		return mPickedFiles;
+	}
+	else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
+	{
+		mPickedFiles.clear();
 
-	sendMessage(message);
+		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
+		message.setValueBoolean("blocking_request", true);
+		message.setValueBoolean("multiple_files", true);
+
+		sendMessage(message);
+
+		return mPickedFiles;
+	}
+	else if (dialog_type == dullahan::FD_SAVE_FILE)
+	{
+		mAuthOK = false;
+
+		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
+		message.setValue("filename", default_file);
 
-	return mPickedFile;
+		sendMessage(message);
+
+		return std::vector<std::string>();
+	}
+
+	return std::vector<std::string>();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
 void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
 {
 	std::string name = "";
@@ -343,6 +388,8 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
 	sendMessage(message);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
 void MediaPluginCEF::authResponse(LLPluginMessage &message)
 {
 	mAuthOK = message.getValueBoolean("ok");
@@ -375,7 +422,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
 				message.setValueLLSD("versions", versions);
 
-				std::string plugin_version = "CEF plugin 1.1.3";
+				std::string plugin_version = "CEF plugin 1.1.412";
 				message.setValue("plugin_version", plugin_version);
 				sendMessage(message);
 			}
@@ -441,17 +488,17 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
 				mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
 				mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
+				mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
 				mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
-				mCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));
+				mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
 				mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
-				mCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1));
-				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialogCallback, this));
+				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
 				mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
 				mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
 
 				dullahan::dullahan_settings settings;
 				settings.accept_language_list = mHostLanguage;
-				settings.background_color = 0xffffffff;
+				settings.background_color = 0xff282828;
 				settings.cache_enabled = true;
 				settings.cache_path = mCachePath;
 				settings.cookie_store_path = mCookiePath;
@@ -470,6 +517,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.plugins_enabled = mPluginsEnabled;
 				settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
 				settings.webgl_enabled = true;
+				settings.log_file = mCefLogFile;
+				settings.log_verbose = mCefLogVerbose;
 
 				std::vector<std::string> custom_schemes(1, "secondlife");
 				mCEFLib->setCustomSchemes(custom_schemes);
@@ -499,8 +548,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				std::string user_data_path_cache = message_in.getValue("cache_path");
 				std::string user_data_path_cookies = message_in.getValue("cookies_path");
+
 				mCachePath = user_data_path_cache + "cef_cache";
 				mCookiePath = user_data_path_cookies + "cef_cookies";
+				mCefLogFile = message_in.getValue("cef_log_file");
+				mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
 			}
 			else if (message_name == "size_change")
 			{
@@ -522,11 +574,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 
 						mTextureWidth = texture_width;
 						mTextureHeight = texture_height;
+
+						mCEFLib->setSize(mWidth, mHeight);
 					};
 				};
 
-				mCEFLib->setSize(mWidth, mHeight);
-
 				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
 				message.setValue("name", name);
 				message.setValueS32("width", width);
@@ -652,7 +704,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			if (message_name == "pick_file_response")
 			{
-				mPickedFile = message_in.getValue("file");
+				LLSD file_list_llsd = message_in.getValueLLSD("file_list");
+
+				LLSD::array_const_iterator iter = file_list_llsd.beginArray();
+				LLSD::array_const_iterator end = file_list_llsd.endArray();
+				for (; iter != end; ++iter)
+				{
+					mPickedFiles.push_back(((*iter).asString()));
+				}
 			}
 			if (message_name == "auth_response")
 			{
@@ -699,6 +758,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				mCookiesEnabled = message_in.getValueBoolean("enable");
 			}
+			else if (message_name == "clear_cookies")
+			{
+				mCEFLib->deleteAllCookies();
+			}
 			else if (message_name == "set_user_agent")
 			{
 				mUserAgentSubtring = message_in.getValue("user_agent");
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index cdb98d26e4e806a8c7728f8e1c758f97d4047017..76e9e619d633967075525c0a9191d24f652f1c4b 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-5.1.3
+5.1.4
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 75c7ee002b26984dede44967bdcf3312b7e4ba7a..45e2fc9bf0552ad723ce09074db9b85443d23032 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16167,6 +16167,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>CefVerboseLog</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable/disable CEF verbose loggingk</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
 </map>
 </llsd>
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c33c0d56845d28056ba5741c54a8664096829505..ce4aab20c7f6942a9be068e2646eaa7c5b64e650 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1930,8 +1930,6 @@ bool LLAppViewer::cleanup()
 
 	LLAvatarIconIDCache::getInstance()->save();
 	
-	LLViewerMedia::saveCookieFile();
-
 	// Stop the plugin read thread if it's running.
 	LLPluginProcessParent::setUseReadThread(false);
 
@@ -3166,8 +3164,14 @@ LLSD LLAppViewer::getViewerInfo() const
 	cef_ver_codec << " / CEF: ";
 	cef_ver_codec << CEF_VERSION;
 
-	cef_ver_codec << " / Chrome: ";
+	cef_ver_codec << " / Chromium: ";
 	cef_ver_codec << CHROME_VERSION_MAJOR;
+	cef_ver_codec << ".";
+	cef_ver_codec << CHROME_VERSION_MINOR;
+	cef_ver_codec << ".";
+	cef_ver_codec << CHROME_VERSION_BUILD;
+	cef_ver_codec << ".";
+	cef_ver_codec << CHROME_VERSION_PATCH;
 
 	info["LIBCEF_VERSION"] = cef_ver_codec.str();
 #else
diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp
index b1d6d8be822630b349a4ad88d7d1d9d3328d5c7a..e84cbc289f2d6377ebc6886023803d116397164f 100644
--- a/indra/newview/llfloaterfacebook.cpp
+++ b/indra/newview/llfloaterfacebook.cpp
@@ -1,4 +1,4 @@
-/** 
+/**
 * @file llfloaterfacebook.cpp
 * @brief Implementation of llfloaterfacebook
 * @author Gilbert@lindenlab.com
@@ -41,7 +41,6 @@
 #include "llresmgr.h"		// LLLocale
 #include "llsdserialize.h"
 #include "llloadingindicator.h"
-#include "llplugincookiestore.h"
 #include "llslurl.h"
 #include "lltrans.h"
 #include "llsnapshotlivepreview.h"
@@ -296,16 +295,11 @@ void LLFacebookStatusPanel::showConnectedLayout()
 void LLFacebookStatusPanel::onConnect()
 {
     LLFacebookConnect::instance().checkConnectionToFacebook(true);
-
-    //Clear only the facebook browser cookies so that the facebook login screen appears
-    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
 }
 
 void LLFacebookStatusPanel::onDisconnect()
 {
     LLFacebookConnect::instance().disconnectFromFacebook();
-
-    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
 }
 
 void LLFacebookStatusPanel::clearAndClose()
@@ -810,7 +804,7 @@ void LLFacebookCheckinPanel::sendCheckin()
     LLAgentUI::buildSLURL(slurl);
     std::string slurl_string = slurl.getSLURLString();
 
-    // Use a valid http:// URL if the scheme is secondlife:// 
+    // Use a valid http:// URL if the scheme is secondlife://
     LLURI slurl_uri(slurl_string);
     if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
     {
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
index 15b7c7fafadde6599a58386eed1312ef84f41499..69a92b2b54c06cec017933cd77c295c2adf2e93e 100644
--- a/indra/newview/llfloaterflickr.cpp
+++ b/indra/newview/llfloaterflickr.cpp
@@ -40,7 +40,6 @@
 #include "llresmgr.h"		// LLLocale
 #include "llsdserialize.h"
 #include "llloadingindicator.h"
-#include "llplugincookiestore.h"
 #include "llslurl.h"
 #include "lltrans.h"
 #include "llsnapshotlivepreview.h"
@@ -660,16 +659,11 @@ void LLFlickrAccountPanel::showConnectedLayout()
 void LLFlickrAccountPanel::onConnect()
 {
 	LLFlickrConnect::instance().checkConnectionToFlickr(true);
-
-	//Clear only the flickr browser cookies so that the flickr login screen appears
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
 }
 
 void LLFlickrAccountPanel::onDisconnect()
 {
 	LLFlickrConnect::instance().disconnectFromFlickr();
-
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
 }
 
 ////////////////////////
diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
index 803c80ac1a4a869fee36cc19a69082db9e9845c1..2b33bc69356d7b565c65d1653938883236799d0f 100644
--- a/indra/newview/llfloatertwitter.cpp
+++ b/indra/newview/llfloatertwitter.cpp
@@ -41,7 +41,6 @@
 #include "llresmgr.h"		// LLLocale
 #include "llsdserialize.h"
 #include "llloadingindicator.h"
-#include "llplugincookiestore.h"
 #include "llslurl.h"
 #include "lltrans.h"
 #include "llsnapshotlivepreview.h"
@@ -683,16 +682,11 @@ void LLTwitterAccountPanel::showConnectedLayout()
 void LLTwitterAccountPanel::onConnect()
 {
 	LLTwitterConnect::instance().checkConnectionToTwitter(true);
-
-	//Clear only the twitter browser cookies so that the twitter login screen appears
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
 }
 
 void LLTwitterAccountPanel::onDisconnect()
 {
 	LLTwitterConnect::instance().disconnectFromTwitter();
-
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
 }
 
 ////////////////////////
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 9a11680d422feb30446c910e6e429206b17ad71f..491671c46f8f3c1f79fc7b6b6ae48d4651499806 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -615,7 +615,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
         {
             LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
 
-            LLUUID agent_id = from_id;
+            LLUUID agent_id;
             U8 has_inventory;
             U8 asset_type = 0;
             LLUUID group_id;
@@ -680,6 +680,29 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                 item_name = ll_safe_string((const char*)notice_bin_bucket->item_name);
             }
 
+            if (group_id != from_id)
+            {
+                agent_id = from_id;
+            }
+            else
+            {
+                S32 index = original_name.find(" Resident");
+                if (index != std::string::npos)
+                {
+                    original_name = original_name.substr(0, index);
+                }
+
+                // The group notice packet does not have an AgentID.  Obtain one from the name cache.
+                // If last name is "Resident" strip it out so the cache name lookup works.
+                std::string legacy_name = gCacheName->buildLegacyName(original_name);
+                agent_id = LLAvatarNameCache::findIdByName(legacy_name);
+
+                if (agent_id.isNull())
+                {
+                    LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL;
+                }
+            }
+
             if (agent_id.notNull() && LLMuteList::getInstance()->isMuted(agent_id))
             {
                 break;
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index a8025906c7e2c27ee9e7d512b1ce19d0c2b830c2..7f6955d08cccaff5953c418da15d45237de5e4da 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1022,7 +1022,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			// try as slurl first
 			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
 			{
-				LLWeb::loadURL(url, target, std::string());
+				LLWeb::loadURL(url, target, uuid);
 			}
 
 			// CP: removing this code because we no longer support popups so this breaks the flow.
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 2ed2f8644e622b34b7af5399f2ab57a88d2dd258..62560a2fc8cee0c3fd5523025c8f7f822c93de8b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -972,9 +972,6 @@ bool idle_startup()
 		// Load Avatars icons cache
 		LLAvatarIconIDCache::getInstance()->load();
 		
-		// Load media plugin cookies
-		LLViewerMedia::loadCookieFile();
-
 		LLRenderMuteList::getInstance()->loadFromFile();
 
 		//-------------------------------------------------
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f4b5055cd9504d5385561818186db91e94ddfc97..75108b3ef0dfc67acdc83e717084e5cf25776e27 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -50,7 +50,6 @@
 #include "llpanelprofile.h"
 #include "llparcel.h"
 #include "llpluginclassmedia.h"
-#include "llplugincookiestore.h"
 #include "llurldispatcher.h"
 #include "lluuid.h"
 #include "llversioninfo.h"
@@ -154,7 +153,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver()
 }
 
 
-LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
 LLURL LLViewerMedia::sOpenIDURL;
 std::string LLViewerMedia::sOpenIDCookie;
 LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
@@ -169,8 +167,6 @@ static F64 sLowestLoadableImplInterest = 0.0f;
 static bool sAnyMediaShowing = false;
 static bool sAnyMediaPlaying = false;
 static boost::signals2::connection sTeleportFinishConnection;
-static std::string sUpdatedCookies;
-static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
 
 //////////////////////////////////////////////////////////////////////////////////////////
 static void add_media_impl(LLViewerMediaImpl* media)
@@ -610,12 +606,6 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 
 	sAnyMediaShowing = false;
 	sAnyMediaPlaying = false;
-	sUpdatedCookies = getCookieStore()->getChangedCookies();
-	if(!sUpdatedCookies.empty())
-	{
-		LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL;
-		LL_DEBUGS() << sUpdatedCookies << LL_ENDL;
-	}
 
 	impl_list::iterator iter = sViewerMediaImplList.begin();
 	impl_list::iterator end = sViewerMediaImplList.end();
@@ -1059,64 +1049,6 @@ void LLViewerMedia::clearAllCookies()
 			pimpl->mMediaSource->clear_cookies();
 		}
 	}
-
-	// Clear all cookies from the cookie store
-	getCookieStore()->setAllCookies("");
-
-	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
-	// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded.
-	// Until such time as we can centralize cookie storage, the following hack should cover these cases:
-
-	// HACK: Look for cookie files in all possible places and delete them.
-	// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file)
-
-	// Places that cookie files can be:
-	// <getOSUserAppDir>/browser_profile/cookies
-	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
-	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!)
-
-	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
-	std::string target;
-	std::string filename;
-
-	LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL;
-
-	// The non-logged-in version is easy
-	target = base_dir;
-	target += "browser_profile";
-	target += gDirUtilp->getDirDelimiter();
-	target += "cookies";
-	LL_DEBUGS() << "target = " << target << LL_ENDL;
-	if(LLFile::isfile(target))
-	{
-		LLFile::remove(target);
-	}
-
-	// the hard part: iterate over all user directories and delete the cookie file from each one
-	LLDirIterator dir_iter(base_dir, "*_*");
-	while (dir_iter.next(filename))
-	{
-		target = gDirUtilp->add(base_dir, filename);
-		gDirUtilp->append(target, "browser_profile");
-		gDirUtilp->append(target, "cookies");
-		LL_DEBUGS() << "target = " << target << LL_ENDL;
-		if(LLFile::isfile(target))
-		{
-			LLFile::remove(target);
-		}
-
-		// Other accounts may have new-style cookie files too -- delete them as well
-		target = gDirUtilp->add(base_dir, filename);
-		gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
-		LL_DEBUGS() << "target = " << target << LL_ENDL;
-		if(LLFile::isfile(target))
-		{
-			LLFile::remove(target);
-		}
-	}
-
-	// If we have an OpenID cookie, re-add it to the cookie store.
-	setOpenIDCookie(std::string());
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1145,7 +1077,7 @@ void LLViewerMedia::setCookiesEnabled(bool enabled)
 		LLViewerMediaImpl* pimpl = *iter;
 		if(pimpl->mMediaSource)
 		{
-			pimpl->mMediaSource->enable_cookies(enabled);
+			pimpl->mMediaSource->cookies_enabled(enabled);
 		}
 	}
 }
@@ -1170,127 +1102,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 /////////////////////////////////////////////////////////////////////////////////////////
-// static
-LLPluginCookieStore *LLViewerMedia::getCookieStore()
-{
-	if(sCookieStore == NULL)
-	{
-		sCookieStore = new LLPluginCookieStore;
-	}
-
-	return sCookieStore;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::loadCookieFile()
-{
-	// build filename for each user
-	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
-
-	if (resolved_filename.empty())
-	{
-		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
-		return;
-	}
-
-	// open the file for reading
-	llifstream file(resolved_filename.c_str());
-	if (!file.is_open())
-	{
-		LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL;
-		return;
-	}
-
-	getCookieStore()->readAllCookies(file, true);
-
-	file.close();
-
-	// send the clear_cookies message to all loaded plugins
-	impl_list::iterator iter = sViewerMediaImplList.begin();
-	impl_list::iterator end = sViewerMediaImplList.end();
-	for (; iter != end; iter++)
-	{
-		LLViewerMediaImpl* pimpl = *iter;
-		if(pimpl->mMediaSource)
-		{
-			pimpl->mMediaSource->clear_cookies();
-		}
-	}
-
-	// If we have an OpenID cookie, re-add it to the cookie store.
-	setOpenIDCookie(std::string());
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::saveCookieFile()
-{
-	// build filename for each user
-	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
-
-	if (resolved_filename.empty())
-	{
-		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
-		return;
-	}
-
-	// open a file for writing
-	llofstream file(resolved_filename.c_str());
-	if (!file.is_open())
-	{
-		LL_WARNS() << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << LL_ENDL;
-		return;
-	}
-
-	getCookieStore()->writePersistentCookies(file);
-
-	file.close();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure)
-{
-	std::stringstream cookie;
-
-	cookie << name << "=" << LLPluginCookieStore::quoteString(value);
-
-	if(expires.notNull())
-	{
-		cookie << "; expires=" << expires.asRFC1123();
-	}
-
-	cookie << "; domain=" << domain;
-
-	cookie << "; path=" << path;
-
-	if(secure)
-	{
-		cookie << "; secure";
-	}
-
-	getCookieStore()->setCookies(cookie.str());
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure)
-{
-	// A session cookie just has a NULL date.
-	addCookie(name, value, domain, LLDate(), path, secure);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
-{
-	// To remove a cookie, add one with the same name, domain, and path that expires in the past.
-
-	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
-}
-
+//// static
 
 LLSD LLViewerMedia::getHeaders()
 {
@@ -1395,8 +1207,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
         hostEnd = authority.size();
     }
 
-    getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
-
 	if (url.length())
 	{
 		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
@@ -1434,7 +1244,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
     httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
     httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
 
-
     LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
     LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
     
@@ -1459,13 +1268,9 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
     const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
     LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
 
-    // *TODO: What about bad status codes?  Does this destroy previous cookies?
-    LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
-
     // Set cookie for snapshot publishing.
     std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
     LLWebProfile::setAuthCookie(authCookie);
-
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1660,12 +1465,6 @@ void LLViewerMedia::cleanupClass()
 		delete sSpareBrowserMediaSource;
 		sSpareBrowserMediaSource = NULL;
 	}
-
-	if (sCookieStore != NULL)
-	{
-		delete sCookieStore;
-		sCookieStore = NULL;
-	}
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1898,6 +1697,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
 		user_data_path_cookies += gDirUtilp->getDirDelimiter();
 
+		std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
+
 		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
 		// If the linden username returned is blank, that can only mean we are
 		// at the login page displaying login Web page or Web browser test via Develop menu.
@@ -1906,7 +1707,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		std::string linden_user_dir = gDirUtilp->getLindenUserDir();
 		if ( ! linden_user_dir.empty() )
 		{
-			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
 			user_data_path_cookies = linden_user_dir;
 			user_data_path_cookies += gDirUtilp->getDirDelimiter();
 		};
@@ -1927,13 +1727,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		{
 			media_source = new LLPluginClassMedia(owner);
 			media_source->setSize(default_width, default_height);
-			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
+			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
 			media_source->setLanguageCode(LLUI::getLanguage());
 			media_source->setZoomFactor(zoom_factor);
 
 			// collect 'cookies enabled' setting from prefs and send to embedded browser
 			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
-			media_source->enable_cookies( cookies_enabled || clean_browser);
+			media_source->cookies_enabled( cookies_enabled || clean_browser);
 
 			// collect 'plugins enabled' setting from prefs and send to embedded browser
 			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
@@ -2040,17 +1840,6 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 			media_source->clear_cache();
 		}
 
-		// TODO: Only send cookies to plugins that need them
-		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
-		//  Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message,
-		//  which could cause odd race conditions.
-		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies();
-		LL_DEBUGS() << "setting cookies: " << all_cookies << LL_ENDL;
-		if(!all_cookies.empty())
-		{
-			media_source->set_cookies(all_cookies);
-		}
-
 		mMediaSource = media_source;
 		mMediaSource->setDeleteOK(false) ;
 		updateVolume();
@@ -2992,14 +2781,10 @@ void LLViewerMediaImpl::update()
 		updateVolume();
 
 		// TODO: this is updated every frame - is this bad?
-		updateJavascriptObject();
-
-		// If we didn't just create the impl, it may need to get cookie updates.
-		if(!sUpdatedCookies.empty())
-		{
-			// TODO: Only send cookies to plugins that need them
-			mMediaSource->set_cookies(sUpdatedCookies);
-		}
+		// Removing this as part of the post viewer64 media update
+		// Removed as not implemented in CEF embedded browser
+		// See MAINT-8194 for a more fuller description
+		// updateJavascriptObject();
 	}
 
 
@@ -3489,22 +3274,40 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 
 		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
 		{
-			// Display a file picker
-			std::string response;
-
 			LLFilePicker& picker = LLFilePicker::instance();
-			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
+			std::vector<std::string> responses;
+
+			bool pick_multiple_files = plugin->getIsMultipleFilePick();
+			if (pick_multiple_files == false)
 			{
-				// The user didn't pick a file -- the empty response string will indicate this.
+				picker.getOpenFile(LLFilePicker::FFLOAD_ALL);
+
+				std::string filename = picker.getFirstFile();
+				responses.push_back(filename);
 			}
+			else
+			{
+				if (picker.getMultipleOpenFiles())
+				{
+					std::string filename = picker.getFirstFile();
 
-			response = picker.getFirstFile();
+					responses.push_back(filename);
 
-			plugin->sendPickFileResponse(response);
+					while (!filename.empty())
+					{
+						filename = picker.getNextFile();
+
+						if (!filename.empty())
+						{
+							responses.push_back(filename);
+						}
+					}
+				}
+			}
+			plugin->sendPickFileResponse(responses);
 		}
 		break;
 
-
 		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
 		{
 			LLNotification::Params auth_request_params;
@@ -3572,13 +3375,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// virtual
-void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie)
-{
-	LLViewerMedia::getCookieStore()->setCookies(cookie);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // virtual
 void
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 0212bf88bf7514bffd332428b7dbc77885a474d7..6e18c4fecba11d90eb9bf444dc7a33ba2eeb6905 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -50,7 +50,6 @@ class LLViewerMediaTexture;
 class LLMediaEntry;
 class LLVOVolume;
 class LLMimeDiscoveryResponder;
-class LLPluginCookieStore;
 
 typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
 ///////////////////////////////////////////////////////////////////////////////
@@ -149,13 +148,6 @@ class LLViewerMedia
 	// Set the proxy config for all loaded plugins
 	static void setProxyConfig(bool enable, const std::string &host, int port);
 	
-	static LLPluginCookieStore *getCookieStore();
-	static void loadCookieFile();
-	static void saveCookieFile();
-	static void addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path = std::string("/"), bool secure = false );
-	static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );
-	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
-
 	static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
 	static void openIDCookieResponse(const std::string& url, const std::string &cookie);
 	
@@ -178,7 +170,6 @@ class LLViewerMedia
     static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
     static void getOpenIDCookieCoro(std::string url);
 
-	static LLPluginCookieStore *sCookieStore;
 	static LLURL sOpenIDURL;
 	static std::string sOpenIDCookie;
 	static LLPluginClassMedia* sSpareBrowserMediaSource;
@@ -337,7 +328,6 @@ class LLViewerMediaImpl
 
 	// Inherited from LLPluginClassMediaOwner
 	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
-	/*virtual*/ void handleCookieSet(LLPluginClassMedia* self, const std::string &cookie);
 
 	// LLEditMenuHandler overrides
 	/*virtual*/ void	cut();
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 06ce4975106b5c3c9742deb48aa8bd4efdf5f70a..81d4e30a7ae747c6e7514085c59d02eebd2612d9 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -31,7 +31,6 @@
 // libs
 #include "llbufferstream.h"
 #include "llimagepng.h"
-#include "llplugincookiestore.h"
 
 #include "llsdserialize.h"
 
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 60f36770bbae93cb642f82bf18e65dfa082b1b6e..71f4d811954223ac8b6046039e85c531f75b3d9f 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -8,14 +8,14 @@
  help_topic="floater_about"
  save_rect="true"
  title="ABOUT [CAPITALIZED_APP_NAME]"
- width="470">
+ width="500">
   
   <tab_container
     follows="all" 
     top="25"
     left="10"
     height="405" 
-    width="450" 
+    width="480" 
     name="about_tab"
     tab_position="top">
     <panel
@@ -33,7 +33,7 @@
        max_length="65536"
        name="support_editor"
        top="5"
-       width="435"
+       width="465"
        word_wrap="true" />
       <button
         follows="left|top" 
@@ -56,7 +56,7 @@
           left="5"
           name="linden_intro"
           top="10"
-          width="435"
+          width="465"
           wrap="true">
 Second Life is brought to you by the Lindens, 
 with open source contributions from:
@@ -71,7 +71,7 @@ with open source contributions from:
        max_length="65536"
        name="contrib_names"
        top_pad="10"
-       width="435"
+       width="465"
        word_wrap="true">
 Dummy Name replaced at run time
       </text_editor>
@@ -91,7 +91,7 @@ Dummy Name replaced at run time
        max_length="65536"
        name="licenses_editor"
        top="5"
-       width="435"
+       width="465"
        word_wrap="true">
         3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
         APR Copyright (C) 2011 The Apache Software Foundation
diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml
index fe9ffba6cd4baebc41f0c7f1f243ab525bf898eb..9a097d933bb513ab03a7f6ee680e63e460296724 100644
--- a/indra/newview/skins/default/xui/en/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -178,108 +178,7 @@
         width="22">
         <button.commit_callback
           function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
-      </button>
-
-      <button
-        image_overlay="Video_URL_Off"
-            image_disabled="PushButton_Disabled"
-            image_disabled_selected="PushButton_Disabled"
-            image_selected="PushButton_Selected"
-            image_unselected="PushButton_Off"
-        chrome="true"
-        tool_tip="MPEG4 Video Test"
-        enabled="true"
-        follows="left|top"
-        height="22"
-        layout="topleft"
-        left="27"
-        name="VLC Plugin Test"
-        top="0"
-        width="22">
-        <button.commit_callback
-          function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/>
-      </button>
-      <button
-        image_overlay="Video_URL_Off"
-            image_disabled="PushButton_Disabled"
-            image_disabled_selected="PushButton_Disabled"
-            image_selected="PushButton_Selected"
-            image_unselected="PushButton_Off"
-        chrome="true"
-        tool_tip="MKV Video Test"
-        enabled="true"
-        follows="left|top"
-        height="22"
-        layout="topleft"
-        left="51"
-        name="VLC Plugin Test"
-        top="0"
-        width="22">
-        <button.commit_callback
-          function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/>
-      </button>
-      <button
-        image_overlay="Video_URL_Off"
-            image_disabled="PushButton_Disabled"
-            image_disabled_selected="PushButton_Disabled"
-            image_selected="PushButton_Selected"
-            image_unselected="PushButton_Off"
-        chrome="true"
-        tool_tip="WebM Video Test"
-        enabled="true"
-        follows="left|top"
-        height="22"
-        layout="topleft"
-        left="75"
-        name="VLC Plugin Test"
-        top="0"
-        width="22">
-        <button.commit_callback
-          function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/>
-      </button>
-      <button
-        image_overlay="Video_URL_Off"
-            image_disabled="PushButton_Disabled"
-            image_disabled_selected="PushButton_Disabled"
-            image_selected="PushButton_Selected"
-            image_unselected="PushButton_Off"
-        chrome="true"
-        tool_tip="MP3 audio Test"
-        enabled="true"
-        follows="left|top"
-        height="22"
-        layout="topleft"
-        left="99"
-        name="VLC Plugin Test"
-        top="0"
-        width="22">
-        <button.commit_callback
-          function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/>
-      </button>
-      <button
-        image_overlay="Video_URL_Off"
-            image_disabled="PushButton_Disabled"
-            image_disabled_selected="PushButton_Disabled"
-            image_selected="PushButton_Selected"
-            image_unselected="PushButton_Off"
-        chrome="true"
-        tool_tip="FLV Test"
-        enabled="true"
-        follows="left|top"
-        height="22"
-        layout="topleft"
-        left="123"
-        name="VLC Plugin Test"
-        top="0"
-        width="22">
-        <button.commit_callback
-          function="WebContent.TestURL"
-          parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/>
+          parameter="https://sl-viewer-media-system.s3.amazonaws.com/index.html"/>
       </button>
     </layout_panel>
     <layout_panel
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 4e2f81902319843547452dc13f07e04aa10969de..07b3cc3bd8d949d9ed9ab02d2c8dd67f3e7d6c5b 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -245,7 +245,7 @@
        name="Media Browser">
         <menu_item_call.on_click
          function="Advanced.WebContentTest"
-         parameter="http://google.com"/>
+         parameter="http://duckduckgo.com"/>
       </menu_item_call>
       <menu
        create_jump_keys="true"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index fa15fb06574fb2a36af47d643778c63fbc388c53..dcd8f0b495c735cf7ffa8a59bf57c5cc4612087f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3163,7 +3163,7 @@
            shortcut="control|alt|shift|Z">
             <menu_item_call.on_click
              function="Advanced.WebContentTest"
-             parameter="http://google.com"/>
+             parameter="http://duckduckgo.com"/>
           </menu_item_call>
           <menu_item_call
            label="FB Connect Test"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 284688d4d15b4026bcb2ff9ca62e82acbdb3d681..2ec5cef640373c1d03989f28e89b2067fb2169ae 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -19,7 +19,7 @@
       follows="left|top"
       height="23"
       label="Clear History"
-      tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+      tool_tip="Clear login image, last location, teleport history, web and texture cache"
       layout="topleft"
       left="30"
       name="clear_cache"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 1d4cbca1a56a0c840d0fd80964d1f61f00771bf8..6732f4ff1c4464d54bd511690590d5cb2a0ed426 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -106,38 +106,6 @@
          width="300">
     Web:
   </text>
- <!-- <radio_group
-   control_name="UseExternalBrowser"
-   draw_border="false"
-   follows="top|left"
-   height="40"
-   layout="topleft"
-   left_delta="50"
-   name="use_external_browser"
-   top_pad="-2"
-   width="480">
-    <radio_item
-      height="20"
-      label="Use my browser (IE, Firefox, Safari)"
-      layout="topleft"
-      left_delta="0"
-      name="external"
-      value="true"
-      top="0"
-      tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen."
-      width="480" />
-    <radio_item
-      height="20"
-      label="Use built-in browser"
-      layout="topleft"
-      left="0"
-      name="internal"
-      value=""
-      tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]."
-      top_delta="20"
-      width="480" />
-  </radio_group> -->
-
   <radio_group
    control_name="PreferredBrowserBehavior"
    follows="left|top"
@@ -149,7 +117,7 @@
    width="480">
     <radio_item
       height="20"
-      label="Use my browser (Chrome, Firefox, IE) for all links"
+      label="Use the default system browser for all links"
       layout="topleft"
       left="0"
       name="internal"
@@ -159,17 +127,17 @@
       width="480" />
     <radio_item
       height="20"
-      label="Use built-in browser for Second Life links only"
+      label="Use the built-in browser for Second Life links only"
       layout="topleft"
       left_delta="0"
       name="external"
       value="1"      
-      tool_tip="Use the default system web browser for help, web links, etc. Builtin browser will be used only for LindenLab/SecondLife links."
+      tool_tip="Use the default system web browser for help, web links, etc. The built-in browser will be used only for LindenLab/Second Life links."
       top_delta="20"
       width="480" />
     <radio_item
       height="20"
-      label="Use built-in browser for all links"
+      label="Use the built-in browser for all links"
       layout="topleft"
       left="0"
       name="external_all"
@@ -193,22 +161,6 @@
     radio_style="false"
     width="400"
     top_pad="5"/>
-
-  <check_box
-   top_delta="4"
-   enabled="true"
-   follows="left|top"
-   height="14"
-   initial_value="true"
-   control_name="CookiesEnabled"
-   label="Accept cookies"
-   left_delta="0"
-   mouse_opaque="true" 
-   name="cookies_enabled"
-   radio_style="false"
-   width="400"
-   top_pad="5"/>
-  
   <check_box
     top_delta="4"
     enabled="true"