diff --git a/autobuild.xml b/autobuild.xml
index 3f2bf9a63061981f1f609a63c72f73135c3a6682..9b89883f7f03f7a5a0831dbd636b8db5fb4b0d3e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -556,9 +556,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1937f9f84f0f33563b9d33cf1c8e695a</string>
+              <string>4332ef6c8e8d7462ee42c99045b0cd87</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11646/67094/dullahan-1.1.925_3.3202.1686.gd665578-darwin64-511376.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11702/67585/dullahan-1.1.929_3.3202.1686.gd665578-darwin64-511421.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -568,9 +568,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>08edc9fa2dc586e7a1c7c4b7a6b6c548</string>
+              <string>001b4ae5c536ee625cf2f85e3bdf2d89</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11648/67101/dullahan-1.1.925_3.3202.1686.gd665578-windows-511376.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11703/67592/dullahan-1.1.929_3.3202.1686.gd665578-windows-511421.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -580,16 +580,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b220e427ade837e45a92fffab02c068f</string>
+              <string>90f1926a1e3cd3ae56acd662ad9c0bdc</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11649/67106/dullahan-1.1.925_3.3202.1686.gd665578-windows64-511376.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/11704/67597/dullahan-1.1.929_3.3202.1686.gd665578-windows64-511421.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.1.925_3.3202.1686.gd665578</string>
+        <string>1.1.929_3.3202.1686.gd665578</string>
       </map>
       <key>elfio</key>
       <map>
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 680017204c0639954f02f74a14d2b684a48b6c36..e6a9787da95448131c5c314fd28dbd75184d1108 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -792,15 +792,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);
 }
 
@@ -1090,6 +1097,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")
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 3b0739d044ca7999783bb6d6516d9d3173312880..98c48cd987ce1fa8f5582781c067d2b72671f35a 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);
 
@@ -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/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index dbd33a736bab10f30d35f88d3aab6395fe2cc0a4..558ae75c3c95cac55ceea1bb891e5c6fdd446c50 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -68,7 +68,7 @@ class MediaPluginCEF :
 	void onNavigateURLCallback(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);
-	const 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);
+	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);
@@ -94,7 +94,7 @@ class MediaPluginCEF :
 	bool mCanPaste;
 	std::string mCachePath;
 	std::string mCookiePath;
-	std::string mPickedFile;
+	std::vector<std::string> mPickedFiles;
 	VolumeCatcher mVolumeCatcher;
 	F32 mCurVolume;
 	dullahan* mCEFLib;
@@ -124,7 +124,7 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCanPaste = false;
 	mCachePath = "";
 	mCookiePath = "";
-	mPickedFile = "";
+	mPickedFiles.clear();
 	mCurVolume = 0.0;
 
 	mCEFLib = new dullahan();
@@ -284,21 +284,34 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-const 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)
+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)
 {
 	// do not use the default CEF file picker
 	use_default = false;
 
 	if (dialog_type == dullahan::FD_OPEN_FILE)
 	{
-		mPickedFile.clear();
+		mPickedFiles.clear();
 
 		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
 		message.setValueBoolean("blocking_request", true);
+		message.setValueBoolean("multiple_files", false);
 
 		sendMessage(message);
 
-		return mPickedFile;
+		return mPickedFiles;
+	}
+	else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
+	{
+		mPickedFiles.clear();
+
+		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)
 	{
@@ -309,10 +322,10 @@ const std::string MediaPluginCEF::onFileDialog(dullahan::EFileDialogType dialog_
 
 		sendMessage(message);
 
-		return std::string();
+		return std::vector<std::string>();
 	}
 
-	return std::string();
+	return std::vector<std::string>();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -659,7 +672,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")
 			{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 114f1d327b76d8c6224387ca53553ec60e746d75..9dd8b00ef6d9b40255aed49c731aa717fe4e7dc6 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3480,22 +3480,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;