Index: wp-includes/macros.php
===================================================================
--- wp-includes/macros.php	(revision 0)
+++ wp-includes/macros.php	(revision 0)
@@ -0,0 +1,186 @@
+<?php
+
+/*
+
+An API for creating macro tags that support attributes and enclosed content, such as:
+
+[macro /]
+[macro foo="bar" baz="bing" /]
+[macro foo="bar"]content[/macro]
+
+tag and attrbute parsing regexp code based on the Textpattern tag parser.
+
+To apply macro tags to content:
+
+$out = do_macro($content);
+
+Simplest example of a macro tag using the API:
+
+// [footag foo="bar"]
+function footag_func($atts) {
+	return "foo = {$atts[foo]}";
+}
+add_macro('footag', 'footag_func');
+
+Example with nice attribute defaults:
+
+// [bartag foo="bar"]
+function bartag_func($atts) {
+	extract(macro_atts(array(
+		'foo' => 'no foo',
+		'baz' => 'default baz',
+	), $atts));
+	
+	return "foo = {$foo}";
+}
+add_macro('bartag', 'bartag_func');
+
+Example with enclosed content:
+
+// [baztag]content[/baztag]
+function baztag_func($atts, $content='') {
+	return "content = $content";
+}
+add_macro('baztag', 'baztag_func');
+
+*/
+
+$macro_tags = array();
+
+function add_macro($tag, $func) {
+	global $macro_tags;
+
+	if ( is_callable($func) )
+		$macro_tags[$tag] = $func;
+}
+
+function remove_macro($tag) {
+	global $macro_tags;
+
+	unset($macro_tags[$tag]);
+}
+
+function remove_all_macros() {
+	global $macro_tags;
+
+	$macro_tags = array();
+}
+
+function do_macro($content) {
+	global $macro_tags;
+
+	if (empty($macro_tags) || !is_array($macro_tags))
+		return $content;
+
+	$tagnames = array_keys($macro_tags);
+	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
+
+	$pattern = '/\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?/s';
+
+	return preg_replace_callback($pattern, 'do_macro_tag', $content);
+}
+
+function do_macro_tag($m) {
+	global $macro_tags;
+
+	$tag = $m[1];
+	$attr = macro_parse_atts($m[2]);
+
+	if ( isset($m[4]) ) {
+		// enclosing tag - extra parameter
+		return call_user_func($macro_tags[$tag], $attr, $m[4]);
+	} else {
+		// self-closing tag
+		return call_user_func($macro_tags[$tag], $attr);
+	}
+}
+
+function macro_parse_atts($text) {
+	$atts = array();
+	$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)/';
+	if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) {
+		foreach ($match as $m) {
+			if (!empty($m[1]))
+				$atts[strtolower($m[1])] = stripcslashes($m[2]);
+			elseif (!empty($m[3]))
+				$atts[strtolower($m[3])] = stripcslashes($m[4]);
+			elseif (!empty($m[5]))
+				$atts[strtolower($m[5])] = stripcslashes($m[6]);
+		}
+	}
+	return $atts;
+}
+
+function macro_atts($pairs, $atts) {
+	$out = array();
+	foreach($pairs as $name => $default) {
+		if ( array_key_exists($name, $atts) )
+			$out[$name] = $atts[$name];
+		else
+			$out[$name] = $default;
+	}
+	return $out;
+}
+
+add_macro('thumbs', 'thumbs_macro');
+
+function thumbs_macro($attr) {
+	global $post;
+
+	// Allow plugins/themes to override the default thumbs template.
+	$output = apply_filters('post_thumbs', '', $attr);
+	if ( $output != '' )
+		return $output;
+
+	$attachments = get_children("post_parent=$post->ID&post_type=attachment&orderby=\"menu_order ASC, ID ASC\"");
+/*
+	foreach ( $attachments as $id => $attachment ) {
+		$meta = get_post_custom($id);
+		if ( $meta ) foreach ( $meta as $k => $v )
+			$attachments[$id]->$k = $v;
+		if ( isset($attachments[$id]->_wp_attachment_metadata[0]) )
+			$attachments[$id]->meta = unserialize($attachments[$id]->_wp_attachment_metadata[0]);
+	}
+*/
+
+	$output = "
+		<style type='text/css'>
+			.thumbs {
+				width: 450px;
+				left: 50%;
+				margin: auto;
+			}
+			.thumbs div {
+				float: left;
+				margin-top: 10px;
+				text-align: center;
+				width: 33%;			}
+			.thumbs img {
+				border: 3px solid #cfcfcf;
+			}
+		</style>
+		<div class='thumbs'>
+";
+
+	if ( !empty($attachments) ) foreach ( $attachments as $id => $attachment ) {
+		$src = wp_get_attachment_thumb_url($id);
+		$href = get_attachment_link($id);
+		$output .= "
+			<div>
+				<a href='$href'><img src='$src' alt='$attachment->post_title' /></a>
+			</div>
+";
+		if ( ++$i % 3 == 0 )
+			$output .= '<br style="clear: both" />';
+	}
+
+	$output .= "
+		</div>
+";
+
+	return $output;
+}
+
+add_filter('the_content', 'do_macro');
+
+?>
\ No newline at end of file
Index: wp-includes/js/swfupload/swfupload.js
===================================================================
--- wp-includes/js/swfupload/swfupload.js	(revision 0)
+++ wp-includes/js/swfupload/swfupload.js	(revision 0)
@@ -0,0 +1,1051 @@
+/**
+ * SWFUpload v2.0 by Jacob Roberts, Nov 2007, http://www.swfupload.org, http://linebyline.blogspot.com
+ * -------- -------- -------- -------- -------- -------- -------- --------
+ * SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * See Changelog.txt for version history
+ *
+ * Development Notes:
+ *  * This version of SWFUpload requires Flash Player 9.0.28 and should autodetect the correct flash version.
+ *  * In Linux Flash Player 9 setting the post file variable name does not work. It is always set to "Filedata".
+ *  * There is a lot of repeated code that could be refactored to single functions.  Feel free.
+ *  * It's dangerous to do "circular calls" between Flash and JavaScript. I've taken steps to try to work around issues
+ *     by having the event calls pipe through setTimeout.  However you should still avoid calling in to Flash from
+ *     within the event handler methods.  Especially the "startUpload" event since it cannot use the setTimeout hack.
+ */
+
+
+/* *********** */
+/* Constructor */
+/* *********** */
+
+var SWFUpload = function (init_settings) {
+	this.initSWFUpload(init_settings);
+};
+
+SWFUpload.prototype.initSWFUpload = function (init_settings) {
+	// Remove background flicker in IE (read this: http://misterpixel.blogspot.com/2006/09/forensic-analysis-of-ie6.html)
+	// This doesn't have anything to do with SWFUpload but can help your UI behave better in IE.
+	try {
+		document.execCommand('BackgroundImageCache', false, true);
+	} catch (ex1) {
+	}
+
+
+	try {
+		this.customSettings = {};	// A container where developers can place their own settings associated with this instance.
+		this.settings = {};
+		this.eventQueue = [];
+		this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
+		this.movieElement = null;
+
+		// Setup global control tracking
+		SWFUpload.instances[this.movieName] = this;
+
+		// Load the settings.  Load the Flash movie.
+		this.initSettings(init_settings);
+		this.loadFlash();
+
+		this.displayDebugInfo();
+
+	} catch (ex2) {
+		this.debug(ex2);
+	}
+}
+
+/* *************** */
+/* Static thingies */
+/* *************** */
+SWFUpload.instances = {};
+SWFUpload.movieCount = 0;
+SWFUpload.QUEUE_ERROR = {
+	QUEUE_LIMIT_EXCEEDED	  		: -100,
+	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
+	ZERO_BYTE_FILE			  		: -120,
+	INVALID_FILETYPE		  		: -130
+};
+SWFUpload.UPLOAD_ERROR = {
+	HTTP_ERROR				  		: -200,
+	MISSING_UPLOAD_URL	      		: -210,
+	IO_ERROR				  		: -220,
+	SECURITY_ERROR			  		: -230,
+	UPLOAD_LIMIT_EXCEEDED	  		: -240,
+	UPLOAD_FAILED			  		: -250,
+	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
+	FILE_VALIDATION_FAILED	  		: -270,
+	FILE_CANCELLED			  		: -280,
+	UPLOAD_STOPPED					: -290
+};
+SWFUpload.FILE_STATUS = {
+	QUEUED		 : -1,
+	IN_PROGRESS	 : -2,
+	ERROR		 : -3,
+	COMPLETE	 : -4,
+	CANCELLED	 : -5
+};
+
+
+/* ***************** */
+/* Instance Thingies */
+/* ***************** */
+// init is a private method that ensures that all the object settings are set, getting a default value if one was not assigned.
+
+SWFUpload.prototype.initSettings = function (init_settings) {
+	// Upload backend settings
+	this.addSetting("upload_url",		 		init_settings.upload_url,		  		"");
+	this.addSetting("file_post_name",	 		init_settings.file_post_name,	  		"Filedata");
+	this.addSetting("post_params",		 		init_settings.post_params,		  		{});
+
+	// File Settings
+	this.addSetting("file_types",			  	init_settings.file_types,				"*.*");
+	this.addSetting("file_types_description", 	init_settings.file_types_description, 	"All Files");
+	this.addSetting("file_size_limit",		  	init_settings.file_size_limit,			"1024");
+	this.addSetting("file_upload_limit",	  	init_settings.file_upload_limit,		"0");
+	this.addSetting("file_queue_limit",		  	init_settings.file_queue_limit,			"0");
+
+	// Flash Settings
+	this.addSetting("flash_url",		  		init_settings.flash_url,				"swfupload.swf");
+	this.addSetting("flash_width",		  		init_settings.flash_width,				"1px");
+	this.addSetting("flash_height",		  		init_settings.flash_height,				"1px");
+	this.addSetting("flash_color",		  		init_settings.flash_color,				"#FFFFFF");
+
+	// Debug Settings
+	this.addSetting("debug_enabled", init_settings.debug,  false);
+
+	// Event Handlers
+	this.flashReady_handler         = SWFUpload.flashReady;	// This is a non-overrideable event handler
+	this.swfUploadLoaded_handler    = this.retrieveSetting(init_settings.swfupload_loaded_handler,	    SWFUpload.swfUploadLoaded);
+	
+	this.fileDialogStart_handler	= this.retrieveSetting(init_settings.file_dialog_start_handler,		SWFUpload.fileDialogStart);
+	this.fileQueued_handler			= this.retrieveSetting(init_settings.file_queued_handler,			SWFUpload.fileQueued);
+	this.fileQueueError_handler		= this.retrieveSetting(init_settings.file_queue_error_handler,		SWFUpload.fileQueueError);
+	this.fileDialogComplete_handler	= this.retrieveSetting(init_settings.file_dialog_complete_handler,	SWFUpload.fileDialogComplete);
+	
+	this.uploadStart_handler		= this.retrieveSetting(init_settings.upload_start_handler,			SWFUpload.uploadStart);
+	this.uploadProgress_handler		= this.retrieveSetting(init_settings.upload_progress_handler,		SWFUpload.uploadProgress);
+	this.uploadError_handler		= this.retrieveSetting(init_settings.upload_error_handler,			SWFUpload.uploadError);
+	this.uploadSuccess_handler		= this.retrieveSetting(init_settings.upload_success_handler,		SWFUpload.uploadSuccess);
+	this.uploadComplete_handler		= this.retrieveSetting(init_settings.upload_complete_handler,		SWFUpload.uploadComplete);
+
+	this.debug_handler				= this.retrieveSetting(init_settings.debug_handler,			   		SWFUpload.debug);
+
+	// Other settings
+	this.customSettings = this.retrieveSetting(init_settings.custom_settings, {});
+};
+
+// loadFlash is a private method that generates the HTML tag for the Flash
+// It then adds the flash to the "target" or to the body and stores a
+// reference to the flash element in "movieElement".
+SWFUpload.prototype.loadFlash = function () {
+	var html, target_element, container;
+
+	// Make sure an element with the ID we are going to use doesn't already exist
+	if (document.getElementById(this.movieName) !== null) {
+		return false;
+	}
+
+	// Get the body tag where we will be adding the flash movie
+	try {
+		target_element = document.getElementsByTagName("body")[0];
+		if (typeof(target_element) === "undefined" || target_element === null) {
+			this.debug('Could not find the BODY element. SWFUpload failed to load.');
+			return false;
+		}
+	} catch (ex) {
+		return false;
+	}
+
+	// Append the container and load the flash
+	container = document.createElement("div");
+	container.style.width = this.getSetting("flash_width");
+	container.style.height = this.getSetting("flash_height");
+
+	target_element.appendChild(container);
+	container.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
+};
+
+// Generates the embed/object tags needed to embed the flash in to the document
+SWFUpload.prototype.getFlashHTML = function () {
+	var html = "";
+
+	// Create Mozilla Embed HTML
+	if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
+		// Build the basic embed html
+		html = '<embed type="application/x-shockwave-flash" src="' + this.getSetting("flash_url") + '" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '"';
+		html += ' id="' + this.movieName + '" name="' + this.movieName + '" ';
+		html += 'bgcolor="' + this.getSetting("flash_color") + '" quality="high" menu="false" flashvars="';
+
+		html += this.getFlashVars();
+
+		html += '" />';
+
+		// Create IE Object HTML
+	} else {
+
+		// Build the basic Object tag
+		html = '<object id="' + this.movieName + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + this.getSetting("flash_width") + '" height="' + this.getSetting("flash_height") + '">';
+		html += '<param name="movie" value="' + this.getSetting("flash_url") + '">';
+
+		html += '<param name="bgcolor" value="' + this.getSetting("flash_color") + '" />';
+		html += '<param name="quality" value="high" />';
+		html += '<param name="menu" value="false" />';
+
+		html += '<param name="flashvars" value="' + this.getFlashVars() + '" />';
+		html += '</object>';
+	}
+
+	return html;
+};
+
+// This private method builds the parameter string that will be passed
+// to flash.
+SWFUpload.prototype.getFlashVars = function () {
+	// Build a string from the post param object
+	var param_string = this.buildParamString();
+
+	// Build the parameter string
+	var html = "";
+	html += "movieName=" + encodeURIComponent(this.movieName);
+	html += "&uploadURL=" + encodeURIComponent(this.getSetting("upload_url"));
+	html += "&params=" + encodeURIComponent(param_string);
+	html += "&filePostName=" + encodeURIComponent(this.getSetting("file_post_name"));
+	html += "&fileTypes=" + encodeURIComponent(this.getSetting("file_types"));
+	html += "&fileTypesDescription=" + encodeURIComponent(this.getSetting("file_types_description"));
+	html += "&fileSizeLimit=" + encodeURIComponent(this.getSetting("file_size_limit"));
+	html += "&fileUploadLimit=" + encodeURIComponent(this.getSetting("file_upload_limit"));
+	html += "&fileQueueLimit=" + encodeURIComponent(this.getSetting("file_queue_limit"));
+	html += "&debugEnabled=" + encodeURIComponent(this.getSetting("debug_enabled"));
+
+	return html;
+};
+
+SWFUpload.prototype.getMovieElement = function () {
+	if (typeof(this.movieElement) === "undefined" || this.movieElement === null) {
+		this.movieElement = document.getElementById(this.movieName);
+
+		// Fix IEs "Flash can't callback when in a form" issue (http://www.extremefx.com.ar/blog/fixing-flash-external-interface-inside-form-on-internet-explorer)
+		// Removed because Revision 6 always adds the flash to the body (inside a containing div)
+		// If you insist on adding the Flash file inside a Form then in IE you have to make you wait until the DOM is ready
+		// and run this code to make the form's ID available from the window object so Flash and JavaScript can communicate.
+		//if (typeof(window[this.movieName]) === "undefined" || window[this.moveName] !== this.movieElement) {
+		//	window[this.movieName] = this.movieElement;
+		//}
+	}
+
+	return this.movieElement;
+};
+
+SWFUpload.prototype.buildParamString = function () {
+	var post_params = this.getSetting("post_params");
+	var param_string_pairs = [];
+	var i, value, name;
+
+	// Retrieve the user defined parameters
+	if (typeof(post_params) === "object") {
+		for (name in post_params) {
+			if (post_params.hasOwnProperty(name)) {
+				if (typeof(post_params[name]) === "string") {
+					param_string_pairs.push(encodeURIComponent(name) + "=" + encodeURIComponent(post_params[name]));
+				}
+			}
+		}
+	}
+
+	return param_string_pairs.join("&");
+};
+
+// Saves a setting.	 If the value given is undefined or null then the default_value is used.
+SWFUpload.prototype.addSetting = function (name, value, default_value) {
+	if (typeof(value) === "undefined" || value === null) {
+		this.settings[name] = default_value;
+	} else {
+		this.settings[name] = value;
+	}
+
+	return this.settings[name];
+};
+
+// Gets a setting.	Returns empty string if not found.
+SWFUpload.prototype.getSetting = function (name) {
+	if (typeof(this.settings[name]) === "undefined") {
+		return "";
+	} else {
+		return this.settings[name];
+	}
+};
+
+// Gets a setting, if the setting is undefined then return the default value
+// This does not affect or use the interal setting object.
+SWFUpload.prototype.retrieveSetting = function (value, default_value) {
+	if (typeof(value) === "undefined" || value === null) {
+		return default_value;
+	} else {
+		return value;
+	}
+};
+
+
+// It loops through all the settings and displays
+// them in the debug Console.
+SWFUpload.prototype.displayDebugInfo = function () {
+	var key, debug_message = "";
+
+	debug_message += "----- SWFUPLOAD SETTINGS     ----\nID: " + this.moveName + "\n";
+
+	debug_message += this.outputObject(this.settings);
+
+	debug_message += "----- SWFUPLOAD SETTINGS END ----\n";
+	debug_message += "\n";
+
+	this.debug(debug_message);
+};
+SWFUpload.prototype.outputObject = function (object, prefix) {
+	var output = "", key;
+
+	if (typeof(prefix) !== "string") {
+		prefix = "";
+	}
+	if (typeof(object) !== "object") {
+		return "";
+	}
+
+	for (key in object) {
+		if (object.hasOwnProperty(key)) {
+			if (typeof(object[key]) === "object") {
+				output += (prefix + key + ": { \n" + this.outputObject(object[key], "\t" + prefix) + prefix + "}" + "\n");
+			} else {
+				output += (prefix + key + ": " + object[key] + "\n");
+			}
+		}
+	}
+
+	return output;
+};
+
+/* *****************************
+	-- Flash control methods --
+	Your UI should use these
+	to operate SWFUpload
+   ***************************** */
+
+SWFUpload.prototype.selectFile = function () {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SelectFile) === "function") {
+		try {
+			movie_element.SelectFile();
+		}
+		catch (ex) {
+			this.debug("Could not call SelectFile: " + ex);
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+SWFUpload.prototype.selectFiles = function () {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SelectFiles) === "function") {
+		try {
+			movie_element.SelectFiles();
+		}
+		catch (ex) {
+			this.debug("Could not call SelectFiles: " + ex);
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+
+/* Start the upload.  If a file_id is specified that file is uploaded. Otherwise the first
+ * file in the queue is uploaded.  If no files are in the queue then nothing happens.
+ * This call uses setTimeout since Flash will be calling back in to JavaScript
+ */
+SWFUpload.prototype.startUpload = function (file_id) {
+	var self = this;
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.StartUpload) === "function") {
+		setTimeout(
+			function () {
+				try {
+					movie_element.StartUpload(file_id);
+				}
+				catch (ex) {
+					self.debug("Could not call StartUpload: " + ex);
+				}
+			}, 0
+		);
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+/* Cancels a the file upload.  You must specify a file_id */
+SWFUpload.prototype.cancelUpload = function (file_id) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.CancelUpload) === "function") {
+		try {
+			movie_element.CancelUpload(file_id);
+		}
+		catch (ex) {
+			this.debug("Could not call CancelUpload: " + ex);
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+// Stops the current upload.  The file is re-queued.  If nothing is currently uploading then nothing happens.
+SWFUpload.prototype.stopUpload = function () {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.StopUpload) === "function") {
+		try {
+			movie_element.StopUpload();
+		}
+		catch (ex) {
+			this.debug("Could not call StopUpload: " + ex);
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+/* ************************
+ * Settings methods
+ *   These methods change the settings inside SWFUpload
+ *   They shouldn't need to be called in a setTimeout since they
+ *   should not call back from Flash to JavaScript (except perhaps in a Debug call)
+ *   and some need to return data so setTimeout won't work.
+ */
+
+/* Gets the file statistics object.	 It looks like this (where n = number):
+	{
+		files_queued: n,
+		complete_uploads: n,
+		upload_errors: n,
+		uploads_cancelled: n,
+		queue_errors: n
+	}
+*/
+SWFUpload.prototype.getStats = function () {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.GetStats) === "function") {
+		try {
+			return movie_element.GetStats();
+		}
+		catch (ex) {
+			this.debug("Could not call GetStats");
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+};
+SWFUpload.prototype.setStats = function (stats_object) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetStats) === "function") {
+		try {
+			movie_element.SetStats(stats_object);
+		}
+		catch (ex) {
+			this.debug("Could not call SetStats");
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+};
+
+SWFUpload.prototype.setCredentials = function(name, password) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetCredentials) === "function") {
+		try {
+			return movie_element.SetCredentials(name, password);
+		}
+		catch (ex) {
+			this.debug("Could not call SetCredentials");
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+};
+
+SWFUpload.prototype.getFile = function (file_id) {
+	var movie_element = this.getMovieElement();
+			if (typeof(file_id) === "number") {
+				if (movie_element !== null && typeof(movie_element.GetFileByIndex) === "function") {
+					try {
+						return movie_element.GetFileByIndex(file_id);
+					}
+					catch (ex) {
+						this.debug("Could not call GetFileByIndex");
+					}
+				} else {
+					this.debug("Could not find Flash element");
+				}
+			} else {
+				if (movie_element !== null && typeof(movie_element.GetFile) === "function") {
+					try {
+						return movie_element.GetFile(file_id);
+					}
+					catch (ex) {
+						this.debug("Could not call GetFile");
+					}
+				} else {
+					this.debug("Could not find Flash element");
+				}
+			}
+};
+
+SWFUpload.prototype.addFileParam = function (file_id, name, value) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.AddFileParam) === "function") {
+		try {
+			return movie_element.AddFileParam(file_id, name, value);
+		}
+		catch (ex) {
+			this.debug("Could not call AddFileParam");
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+};
+
+SWFUpload.prototype.removeFileParam = function (file_id, name) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.RemoveFileParam) === "function") {
+		try {
+			return movie_element.RemoveFileParam(file_id, name);
+		}
+		catch (ex) {
+			this.debug("Could not call AddFileParam");
+		}
+	} else {
+		this.debug("Could not find Flash element");
+	}
+
+};
+
+SWFUpload.prototype.setUploadURL = function (url) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetUploadURL) === "function") {
+		try {
+			this.addSetting("upload_url", url);
+			movie_element.SetUploadURL(this.getSetting("upload_url"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetUploadURL");
+		}
+	} else {
+		this.debug("Could not find Flash element in setUploadURL");
+	}
+};
+
+SWFUpload.prototype.setPostParams = function (param_object) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetPostParams) === "function") {
+		try {
+			this.addSetting("post_params", param_object);
+			movie_element.SetPostParams(this.getSetting("post_params"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetPostParams");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetPostParams");
+	}
+};
+
+SWFUpload.prototype.setFileTypes = function (types, description) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetFileTypes) === "function") {
+		try {
+			this.addSetting("file_types", types);
+			this.addSetting("file_types_description", description);
+			movie_element.SetFileTypes(this.getSetting("file_types"), this.getSetting("file_types_description"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetFileTypes");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetFileTypes");
+	}
+};
+
+SWFUpload.prototype.setFileSizeLimit = function (file_size_limit) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetFileSizeLimit) === "function") {
+		try {
+			this.addSetting("file_size_limit", file_size_limit);
+			movie_element.SetFileSizeLimit(this.getSetting("file_size_limit"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetFileSizeLimit");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetFileSizeLimit");
+	}
+};
+
+SWFUpload.prototype.setFileUploadLimit = function (file_upload_limit) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetFileUploadLimit) === "function") {
+		try {
+			this.addSetting("file_upload_limit", file_upload_limit);
+			movie_element.SetFileUploadLimit(this.getSetting("file_upload_limit"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetFileUploadLimit");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetFileUploadLimit");
+	}
+};
+
+SWFUpload.prototype.setFileQueueLimit = function (file_queue_limit) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetFileQueueLimit) === "function") {
+		try {
+			this.addSetting("file_queue_limit", file_queue_limit);
+			movie_element.SetFileQueueLimit(this.getSetting("file_queue_limit"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetFileQueueLimit");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetFileQueueLimit");
+	}
+};
+
+SWFUpload.prototype.setFilePostName = function (file_post_name) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetFilePostName) === "function") {
+		try {
+			this.addSetting("file_post_name", file_post_name);
+			movie_element.SetFilePostName(this.getSetting("file_post_name"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetFilePostName");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetFilePostName");
+	}
+};
+
+SWFUpload.prototype.setDebugEnabled = function (debug_enabled) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.SetDebugEnabled) === "function") {
+		try {
+			this.addSetting("debug_enabled", debug_enabled);
+			movie_element.SetDebugEnabled(this.getSetting("debug_enabled"));
+		}
+		catch (ex) {
+			this.debug("Could not call SetDebugEnabled");
+		}
+	} else {
+		this.debug("Could not find Flash element in SetDebugEnabled");
+	}
+};
+
+/* *******************************
+	Internal Event Callers
+	Don't override these! These event callers ensure that your custom event handlers
+	are called safely and in order.
+******************************* */
+
+/* This is the callback method that the Flash movie will call when it has been loaded and is ready to go.
+   Calling this or showUI() "manually" will bypass the Flash Detection built in to SWFUpload.
+   Use a ui_function setting if you want to control the UI loading after the flash has loaded.
+*/
+SWFUpload.prototype.flashReady = function () {
+	// Check that the movie element is loaded correctly with its ExternalInterface methods defined
+	var movie_element = this.getMovieElement();
+	if (movie_element === null || typeof(movie_element.StartUpload) !== "function") {
+		this.debug("ExternalInterface methods failed to initialize.");
+		return;
+	}
+	
+	var self = this;
+	if (typeof(self.flashReady_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.flashReady_handler(); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("flashReady_handler event not defined");
+	}
+};
+
+/*
+	Event Queue.  Rather can call events directly from Flash they events are
+	are placed in a queue and then executed.  This ensures that each event is
+	executed in the order it was called which is not guarenteed when calling
+	setTimeout.  Out of order events was especially problematic in Safari.
+*/
+SWFUpload.prototype.executeNextEvent = function () {
+	var  f = this.eventQueue.shift();
+	if (typeof(f) === "function") {
+		f();
+	}
+}
+
+/* This is a chance to do something before the browse window opens */
+SWFUpload.prototype.fileDialogStart = function () {
+	var self = this;
+	if (typeof(self.fileDialogStart_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.fileDialogStart_handler(); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("fileDialogStart event not defined");
+	}
+};
+
+
+/* Called when a file is successfully added to the queue. */
+SWFUpload.prototype.fileQueued = function (file) {
+	var self = this;
+	if (typeof(self.fileQueued_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.fileQueued_handler(file); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("fileQueued event not defined");
+	}
+};
+
+
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.prototype.fileQueueError = function (file, error_code, message) {
+	var self = this;
+	if (typeof(self.fileQueueError_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() {  self.fileQueueError_handler(file, error_code, message); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("fileQueueError event not defined");
+	}
+};
+
+/* Called after the file dialog has closed and the selected files have been queued.
+	You could call startUpload here if you want the queued files to begin uploading immediately. */
+SWFUpload.prototype.fileDialogComplete = function (num_files_selected) {
+	var self = this;
+	if (typeof(self.fileDialogComplete_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.fileDialogComplete_handler(num_files_selected); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("fileDialogComplete event not defined");
+	}
+};
+
+/* Gets called when a file upload is about to be started.  Return true to continue the upload. Return false to stop the upload.
+	If you return false then uploadError and uploadComplete are called (like normal).
+	
+	This is a good place to do any file validation you need.
+	*/
+SWFUpload.prototype.uploadStart = function (file) {
+	var self = this;
+	if (typeof(self.fileDialogComplete_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.returnUploadStart(self.uploadStart_handler(file)); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("uploadStart event not defined");
+	}
+};
+
+/* Note: Internal use only.  This function returns the result of uploadStart to
+	flash.  Since returning values in the normal way can result in Flash/JS circular
+	call issues we split up the call in a Timeout.  This is transparent from the API
+	point of view.
+*/
+SWFUpload.prototype.returnUploadStart = function (return_value) {
+	var movie_element = this.getMovieElement();
+	if (movie_element !== null && typeof(movie_element.ReturnUploadStart) === "function") {
+		try {
+			movie_element.ReturnUploadStart(return_value);
+		}
+		catch (ex) {
+			this.debug("Could not call ReturnUploadStart");
+		}
+	} else {
+		this.debug("Could not find Flash element in returnUploadStart");
+	}
+};
+
+
+
+/* Called during upload as the file progresses. Use this event to update your UI. */
+SWFUpload.prototype.uploadProgress = function (file, bytes_complete, bytes_total) {
+	var self = this;
+	if (typeof(self.uploadProgress_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.uploadProgress_handler(file, bytes_complete, bytes_total); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("uploadProgress event not defined");
+	}
+};
+
+/* Called when an error occurs during an upload. Use error_code and the SWFUpload.UPLOAD_ERROR constants to determine
+   which error occurred. The uploadComplete event is called after an error code indicating that the next file is
+   ready for upload.  For files cancelled out of order the uploadComplete event will not be called. */
+SWFUpload.prototype.uploadError = function (file, error_code, message) {
+	var self = this;
+	if (typeof(this.uploadError_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.uploadError_handler(file, error_code, message); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("uploadError event not defined");
+	}
+};
+
+/* This gets called when a file finishes uploading and the server-side upload script has completed and returned a 200
+status code. Any text returned by the server is available in server_data.
+**NOTE: The upload script MUST return some text or the uploadSuccess and uploadComplete events will not fire and the
+upload will become 'stuck'. */
+SWFUpload.prototype.uploadSuccess = function (file, server_data) {
+	var self = this;
+	if (typeof(self.uploadSuccess_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.uploadSuccess_handler(file, server_data); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("uploadSuccess event not defined");
+	}
+};
+
+/* uploadComplete is called when the file is uploaded or an error occurred and SWFUpload is ready to make the next upload.
+   If you want the next upload to start to automatically you can call startUpload() from this event. */
+SWFUpload.prototype.uploadComplete = function (file) {
+	var self = this;
+	if (typeof(self.uploadComplete_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.uploadComplete_handler(file); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.debug("uploadComplete event not defined");
+	}
+};
+
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
+   internal debug console.  You can override this event and have messages written where you want. */
+SWFUpload.prototype.debug = function (message) {
+	var self = this;
+	if (typeof(self.debug_handler) === "function") {
+		this.eventQueue[this.eventQueue.length] = function() { self.debug_handler(message); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	} else {
+		this.eventQueue[this.eventQueue.length] = function() { self.debugMessage(message); };
+		setTimeout(function () { self.executeNextEvent();}, 0);
+	}
+};
+
+
+/* **********************************
+	Default Event Handlers.
+	These event handlers are used by default if an overriding handler is
+	not defined in the SWFUpload settings object.
+	
+	JS Note: even though these are defined on the SWFUpload object (rather than the prototype) they
+	are attached (read: copied) to a SWFUpload instance and 'this' is given the proper context.
+   ********************************** */
+
+/* This is a special event handler that has no override in the settings.  Flash calls this when it has
+   been loaded by the browser and is ready for interaction.  You should not override it.  If you need
+   to do something with SWFUpload has loaded then use the swfupload_loaded_handler setting.
+*/
+SWFUpload.flashReady = function () {
+	try {
+		this.debug("Flash called back and is ready.");
+
+		if (typeof(this.swfUploadLoaded_handler) === "function") {
+			this.swfUploadLoaded_handler();
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+};
+
+/* This is a chance to something immediately after SWFUpload has loaded.
+   Like, hide the default/degraded upload form and display the SWFUpload form. */
+SWFUpload.swfUploadLoaded = function () {
+};
+
+/* This is a chance to do something before the browse window opens */
+SWFUpload.fileDialogStart = function () {
+};
+
+
+/* Called when a file is successfully added to the queue. */
+SWFUpload.fileQueued = function (file) {
+};
+
+
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.fileQueueError = function (file, error_code, message) {
+	try {
+		switch (error_code) {
+		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
+			this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			break;
+		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
+			this.debug("Error Code: Zero Byte File, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			break;
+		case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
+			this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			break;
+		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
+			this.debug("Error Code: File extension is not allowed, Message: " + message);
+			break;
+		default:
+			this.debug("Error Code: Unhandled error occured. Errorcode: " + error_code);
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+};
+
+/* Called after the file dialog has closed and the selected files have been queued.
+	You could call startUpload here if you want the queued files to begin uploading immediately. */
+SWFUpload.fileDialogComplete = function (num_files_selected) {
+};
+
+/* Gets called when a file upload is about to be started.  Return true to continue the upload. Return false to stop the upload.
+	If you return false then the uploadError callback is called and then uploadComplete (like normal).
+	
+	This is a good place to do any file validation you need.
+	
+	This is the only function that cannot be called on a setTimeout because it must return a value to Flash.
+	You SHOULD NOT make any calls in to Flash (e.i, changing settings, getting stats, etc).  Flash Player bugs prevent
+	calls in to Flash from working reliably.
+*/
+SWFUpload.uploadStart = function (file) {
+	return true;
+};
+
+// Called during upload as the file progresses
+SWFUpload.uploadProgress = function (file, bytes_complete, bytes_total) {
+	this.debug("File Progress: " + file.id + ", Bytes: " + bytes_complete + ". Total: " + bytes_total);
+};
+
+/* This gets called when a file finishes uploading and the upload script has completed and returned a 200 status code.	Any text returned by the
+server is available in server_data.	 The upload script must return some text or uploadSuccess will not fire (neither will uploadComplete). */
+SWFUpload.uploadSuccess = function (file, server_data) {
+	this.debug("Upload Success: " + file.id + ", Server: " + server_data);
+};
+
+/* This is called last.	 The file is uploaded or an error occurred and SWFUpload is ready to make the next upload.
+	If you want to automatically start the next file just call startUpload from here.
+*/
+SWFUpload.uploadComplete = function (file) {
+	this.debug("Upload Complete: " + file.id);
+};
+
+// Called by SWFUpload JavaScript and Flash functions when debug is enabled.
+// Override this method in your settings to call your own debug message handler
+SWFUpload.debug = function (message) {
+	if (this.getSetting("debug_enabled")) {
+		this.debugMessage(message);
+	}
+};
+
+/* Called when an upload occurs during upload.  For HTTP errors 'message' will contain the HTTP STATUS CODE */
+SWFUpload.uploadError = function (file, errcode, msg) {
+	try {
+		switch (errcode) {
+		case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
+			this.debug("Error Code: File ID specified for upload was not found, Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
+			this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
+			this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.IO_ERROR:
+			this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
+			this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
+			this.debug("Error Code: Upload limit reached, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
+			this.debug("Error Code: Upload Initialization exception, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
+			this.debug("Error Code: uploadStart callback returned false, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
+			this.debug("Error Code: The file upload was cancelled, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
+			break;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
+			this.debug("Error Code: The file upload was stopped, File name: " + file.name + ", File size: " + file.size + ", Message: " + msg);
+			break;
+		default:
+			this.debug("Error Code: Unhandled error occured. Errorcode: " + errcode);
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+};
+
+
+
+/* **********************************
+	Debug Console
+	The debug console is a self contained, in page location
+	for debug message to be sent.  The Debug Console adds
+	itself to the body if necessary.
+
+	The console is automatically scrolled as messages appear.
+	
+	You can override this console (to use FireBug's console for instance) by setting the debug event method to your own function
+	that handles the debug message
+   ********************************** */
+SWFUpload.prototype.debugMessage = function (message) {
+	var exception_message, exception_values;
+
+	if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {
+		exception_message = "";
+		exception_values = [];
+		for (var key in message) {
+			exception_values.push(key + ": " + message[key]);
+		}
+		exception_message = exception_values.join("\n");
+		exception_values = exception_message.split("\n");
+		exception_message = "EXCEPTION: " + exception_values.join("\nEXCEPTION: ");
+		SWFUpload.Console.writeLine(exception_message);
+	} else {
+		SWFUpload.Console.writeLine(message);
+	}
+};
+
+SWFUpload.Console = {};
+SWFUpload.Console.writeLine = function (message) {
+	var console, documentForm;
+
+	try {
+		console = document.getElementById("SWFUpload_Console");
+
+		if (!console) {
+			documentForm = document.createElement("form");
+			document.getElementsByTagName("body")[0].appendChild(documentForm);
+
+			console = document.createElement("textarea");
+			console.id = "SWFUpload_Console";
+			console.style.fontFamily = "monospace";
+			console.setAttribute("wrap", "off");
+			console.wrap = "off";
+			console.style.overflow = "auto";
+			console.style.width = "700px";
+			console.style.height = "350px";
+			console.style.margin = "5px";
+			documentForm.appendChild(console);
+		}
+
+		console.value += message + "\n";
+
+		console.scrollTop = console.scrollHeight - console.clientHeight;
+	} catch (ex) {
+		alert("Exception: " + ex.name + " Message: " + ex.message);
+	}
+};

Property changes on: wp-includes/js/swfupload/swfupload.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/swfupload_f9.swf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: wp-includes/js/swfupload/swfupload_f9.swf
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Index: wp-includes/js/swfupload/plugins/swfupload.documentready.js
===================================================================
--- wp-includes/js/swfupload/plugins/swfupload.documentready.js	(revision 0)
+++ wp-includes/js/swfupload/plugins/swfupload.documentready.js	(revision 0)
@@ -0,0 +1,102 @@
+/*
+	DocumentReady Plug-in
+	
+	This plugin loads SWFUpload as soon as the document is ready.  You should not load SWFUpload inside window.onload using this plugin.
+	You can also chain other functions by calling SWFUpload.DocumentReady(your function).
+	
+	Warning: Embedded Ads or other scripts that overwrite window.onload or use their own document ready functions may interfer with this plugin.  You
+		should not set window.onload when using this plugin.
+	
+	Usage Example:
+	
+	var swfu = new SWFUpload(your settings object);
+	SWFUpload.DocumentReady(function () { alert('Document Ready!'; });
+	
+*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+	// Override iniSWFUpload so SWFUpload gets inited when the document is ready rather than immediately
+	SWFUpload.prototype.initSWFUpload = function (old_initSWFUpload) {
+		return function (init_settings) {
+			var self = this;
+			if  (typeof(old_initSWFUpload) === "function") {
+				SWFUpload.DocumentReady(function () {
+					old_initSWFUpload.call(self, init_settings);
+				});
+			}
+		}
+		
+	}(SWFUpload.prototype.initSWFUpload);
+
+	
+	// The DocumentReady function adds the passed in function to
+	// the functions that will be executed when the document is ready/loaded
+	SWFUpload.DocumentReady = function (fn) {
+		// Add the function to the chain
+		SWFUpload.DocumentReady.InternalOnloadChain = function (previous_link_fn) {
+			return function () {
+				if (typeof(previous_link_fn) === "function") {
+					previous_link_fn();
+				}
+				fn();
+			};
+		}(SWFUpload.DocumentReady.InternalOnloadChain);
+	};
+	SWFUpload.DocumentReady.InternalOnloadChain = null;
+	SWFUpload.DocumentReady.Onload = function () {
+		// Execute the onload function chain
+		if (typeof(SWFUpload.DocumentReady.InternalOnloadChain) === "function") {
+			SWFUpload.DocumentReady.InternalOnloadChain();
+		}
+	};
+	SWFUpload.DocumentReady.SetupComplete = false;
+
+
+	/* ********************************************
+		This portion of the code gets executed as soon it is loaded.
+		It binds the proper event for executing JavaScript is
+		early as possible.  This is a per browser function and so
+		some browser sniffing is used.
+		
+		This solution still has the "exposed" issue (See the Global Delegation section at http://peter.michaux.ca/article/553 )
+		
+		Base solution from http://dean.edwards.name/weblog/2006/06/again/ and http://dean.edwards.name/weblog/2005/09/busted/
+	******************************************** */
+	if (!SWFUpload.DocumentReady.SetupComplete) {
+		// for Internet Explorer (using conditional comments)
+		/*@cc_on @*/
+		/*@if (@_win32)
+		document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
+		var script = document.getElementById("__ie_onload");
+		script.onreadystatechange = function() {
+			if (this.readyState == "complete") {
+				SWFUpload.DocumentReady.Onload(); // call the onload handler
+			}
+		};
+		SWFUpload.DocumentReady.SetupComplete = true;
+		/*@end @*/
+	}
+
+	if (!SWFUpload.DocumentReady.SetupComplete && /WebKit/i.test(navigator.userAgent)) { // sniff
+		var _timer = setInterval(function() {
+			if (/loaded|complete/.test(document.readyState)) {
+				clearInterval(_timer);
+				SWFUpload.DocumentReady.Onload(); // call the onload handler
+			}
+		}, 10);
+		SWFUpload.DocumentReady.SetupComplete = true;
+	}
+
+	/* for Mozilla */
+	if (!SWFUpload.DocumentReady.SetupComplete && document.addEventListener) {
+		document.addEventListener("DOMContentLoaded", SWFUpload.DocumentReady.Onload, false);
+		SWFUpload.DocumentReady.SetupComplete = true;
+	}
+
+	/* for other browsers */
+	if (!SWFUpload.DocumentReady.SetupComplete) {
+		window.onload = SWFUpload.DocumentReady.Onload;
+		SWFUpload.DocumentReady.SetupComplete = true;
+	}
+}
\ No newline at end of file

Property changes on: wp-includes/js/swfupload/plugins/swfupload.documentready.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/plugins/swfupload.queue.js
===================================================================
--- wp-includes/js/swfupload/plugins/swfupload.queue.js	(revision 0)
+++ wp-includes/js/swfupload/plugins/swfupload.queue.js	(revision 0)
@@ -0,0 +1,58 @@
+/*
+	Queue Plug-in
+	
+	Features:
+		cancelQueue method for cancelling the entire queue.
+		All queued files are uploaded when startUpload() is called.
+		If false is returned from uploadComplete then the queue upload is stopped.  If false is not returned (strict comparison) then the queue upload is continued.
+		
+	*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+	SWFUpload.queue = {};
+	
+	SWFUpload.prototype.initSettings = function (old_initSettings) {
+		return function (init_settings) {
+			if (typeof(old_initSettings) === "function") {
+				old_initSettings.call(this, init_settings);
+			}
+			
+			this.customSettings.queue_cancelled_flag = false;
+			
+			this.addSetting("user_upload_complete_handler", init_settings.upload_complete_handler, SWFUpload.uploadComplete);
+			this.uploadComplete_handler = SWFUpload.queue.uploadComplete;
+		};
+	}(SWFUpload.prototype.initSettings);
+
+	SWFUpload.prototype.cancelQueue = function () {
+		var stats = this.getStats();
+		this.customSettings.queue_cancelled_flag = false;
+
+		if (stats.in_progress > 0) {
+			this.customSettings.queue_cancelled_flag = true;
+		}
+		
+		while(stats.files_queued > 0) {
+			this.cancelUpload();
+			stats = this.getStats();
+		}
+	};
+	
+	SWFUpload.queue.uploadComplete = function (file) {
+		var user_upload_complete_handler = this.getSetting("user_upload_complete_handler");
+		var continue_upload = true;
+		if (typeof(user_upload_complete_handler) === "function") {
+			continue_upload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
+		}
+		
+		if (continue_upload) {
+			var stats = this.getStats();
+			if (stats.files_queued > 0 && this.customSettings.queue_cancelled_flag === false) {
+				this.startUpload();
+			} else {
+				this.customSettings.queue_cancelled_flag = false;
+			}
+		}
+	};
+}
\ No newline at end of file

Property changes on: wp-includes/js/swfupload/plugins/swfupload.queue.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/plugins/swfupload.detectionkit.js
===================================================================

Property changes on: wp-includes/js/swfupload/plugins/swfupload.detectionkit.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js
===================================================================
--- wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js	(revision 0)
+++ wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js	(revision 0)
@@ -0,0 +1,63 @@
+/* 
+	SWFUpload Graceful Degradation Plug-in
+
+	This plugin allows SWFUpload to display only if it is loaded successfully.  Otherwise a default form is left displayed.
+	
+	Usage:
+	
+	To use this plugin create two HTML containers. Each should have an ID defined.  One container should hold the SWFUpload UI.  The other should hold the degraded UI.
+	
+	The SWFUpload container should have its CSS "display" property set to "none".
+	
+	If SWFUpload loads successfully the SWFUpload container will be displayed ("display" set to "block") and the
+	degraded container will be hidden ("display" set to "none").
+	
+	Use the settings "swfupload_element_id" and "degraded_element_id" to indicate your container IDs.  The default values are "swfupload_container" and "degraded_container".
+	
+*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+	SWFUpload.gracefulDegradation = {};
+	SWFUpload.prototype.initSettings = function (old_initSettings) {
+		return function (init_settings) {
+			if (typeof(old_initSettings) === "function") {
+				old_initSettings.call(this, init_settings);
+			}
+			
+			this.addSetting("swfupload_element_id",		  		init_settings.swfupload_element_id,				"swfupload_container");
+			this.addSetting("degraded_element_id",		  		init_settings.degraded_element_id,				"degraded_container");
+			this.addSetting("user_swfUploadLoaded_handler",		init_settings.swfupload_loaded_handler,			SWFUpload.swfUploadLoaded);
+
+			this.swfUploadLoaded_handler = SWFUpload.gracefulDegradation.swfUploadLoaded;
+		};
+	}(SWFUpload.prototype.initSettings);
+
+	SWFUpload.gracefulDegradation.swfUploadLoaded = function () {
+		var swfupload_container_id, swfupload_container, degraded_container_id, degraded_container, user_swfUploadLoaded_handler;
+		try {
+			swfupload_element_id = this.getSetting("swfupload_element_id");
+			degraded_element_id = this.getSetting("degraded_element_id");
+			
+			// Show the UI container
+			swfupload_container = document.getElementById(swfupload_element_id);
+			if (swfupload_container !== null) {
+				swfupload_container.style.display = "block";
+
+				// Now take care of hiding the degraded UI
+				degraded_container = document.getElementById(degraded_element_id);
+				if (degraded_container !== null) {
+					degraded_container.style.display = "none";
+				}
+			}
+		} catch (ex) {
+			this.debug(ex);
+		}
+		
+		user_swfUploadLoaded_handler = this.getSetting("user_swfUploadLoaded_handler");
+		if (typeof(user_swfUploadLoaded_handler) === "function") {
+			user_swfUploadLoaded_handler.apply(this);
+		}
+	};
+
+}

Property changes on: wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/plugins/swfupload.cookies.js
===================================================================
--- wp-includes/js/swfupload/plugins/swfupload.cookies.js	(revision 0)
+++ wp-includes/js/swfupload/plugins/swfupload.cookies.js	(revision 0)
@@ -0,0 +1,50 @@
+/*
+	Cookie Plug-in
+	
+	This plug in automatically gets all the cookies for this site and adds them to the post_params.
+	Cookies are loaded only on initialization.  The refreshCookies function can be called to update the post_params.
+	The cookies will override any other post params with the same name.
+*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+	SWFUpload.prototype.initSettings = function (old_initSettings) {
+		return function (init_settings) {
+			if (typeof(old_initSettings) === "function") {
+				old_initSettings.call(this, init_settings);
+			}
+			
+			this.refreshCookies(false);	// The false parameter must be sent since SWFUpload has not initialzed at this point
+		};
+	}(SWFUpload.prototype.initSettings);
+	
+	// refreshes the post_params and updates SWFUpload.  The send_to_flash parameters is optional and defaults to True
+	SWFUpload.prototype.refreshCookies = function (send_to_flash) {
+		if (send_to_flash !== false) send_to_flash = true;
+		
+		// Get the post_params object
+		var post_params = this.getSetting("post_params");
+		
+		// Get the cookies
+		var i, cookie_array = document.cookie.split(';'), ca_length = cookie_array.length, c, eq_index, name, value;
+		for(i = 0; i < ca_length; i++) {
+			c = cookie_array[i];
+			
+			// Left Trim spaces
+			while (c.charAt(0) == " ") {
+				c = c.substring(1, c.length);
+			}
+			eq_index = c.indexOf("=");
+			if (eq_index > 0) {
+				name = c.substring(0, eq_index);
+				value = c.substring(eq_index+1);
+				post_params[name] = value;
+			}
+		}
+		
+		if (send_to_flash) {
+			this.setPostParams(post_params);
+		}
+	};
+
+}

Property changes on: wp-includes/js/swfupload/plugins/swfupload.cookies.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/js/swfupload/handlers.js
===================================================================
--- wp-includes/js/swfupload/handlers.js	(revision 0)
+++ wp-includes/js/swfupload/handlers.js	(revision 0)
@@ -0,0 +1,303 @@
+function fileDialogStart() {
+	jQuery("#media-upload-error").empty();
+}
+
+// progress and success handlers for multimedia multi uploads
+function fileQueuedMultimedia(fileObj) {
+	// Create a progress bar containing the filename
+	jQuery('#multimedia-items').append('<div id="multimedia-item-' + fileObj.id + '" class="multimedia-item"><span class="filename original">' + fileObj.name + '</span><div class="progress"><div class="bar"></div></div></div>');
+
+	// Disable the submit button
+	jQuery('#insert-multimedia').attr('disabled', 'disabled');
+}
+
+function uploadProgressMultimedia(fileObj, bytesDone, bytesTotal) {
+	// Lengthen the progress bar
+	jQuery('#multimedia-item-' + fileObj.id + ' .bar').width(620*bytesDone/bytesTotal);
+}
+
+function uploadSuccessMultimedia(fileObj, serverData) {
+	// if async-upload returned an error message, place it in the multimedia item div and return
+	if ( serverData.match('media-upload-error') ) {
+		jQuery('#multimedia-item-' + fileObj.id).html(serverData);
+		return;
+	}
+
+	// Move the progress bar to 100%
+	jQuery('#multimedia-item-' + fileObj.id + ' .bar').remove();
+
+	// Append the HTML returned by the server -- thumbnail and form inputs
+	jQuery('#multimedia-item-' + fileObj.id).append(serverData);
+
+	// Clone the thumbnail as a "pinkynail" -- a tiny image to the left of the filename
+	jQuery('#multimedia-item-' + fileObj.id + ' .thumbnail').clone().attr('className', 'pinkynail').prependTo('#multimedia-item-' + fileObj.id);
+
+	// Replace the original filename with the new (unique) one assigned during upload
+	jQuery('#multimedia-item-' + fileObj.id + ' .filename.original').replaceWith(jQuery('#multimedia-item-' + fileObj.id + ' .filename.new'));
+
+	// Bind toggle function to a new mask over the progress bar area
+	jQuery('#multimedia-item-' + fileObj.id + ' .progress').clone().empty().addClass('clickmask').bind('click', function(){jQuery(this).siblings('.slidetoggle').slideToggle(150);jQuery(this).siblings('.toggle').toggle();}).appendTo('#multimedia-item-' + fileObj.id);
+
+	// Also bind toggle to the links
+	jQuery('#multimedia-item-' + fileObj.id + ' a.toggle').bind('click', function(){jQuery(this).siblings('.slidetoggle').slideToggle(150);jQuery(this).parent().eq(0).children('.toggle').toggle();jQuery(this).siblings('a.toggle').focus();return false;});
+
+	// Bind AJAX to the new Delete button
+	jQuery('#multimedia-item-' + fileObj.id + ' a.delete').bind('click',function(){jQuery.ajax({url:'admin-ajax.php',type:'post',data:{id:this.id.replace(/del/,''),action:'delete-post',_ajax_nonce:this.href.replace(/^.*wpnonce=/,'')}});jQuery(this).parents(".multimedia-item").eq(0).slideToggle(300, function(){jQuery(this).remove();});return false;});
+}
+
+function uploadCompleteMultimedia(fileObj) {
+	// If no more uploads queued, enable the submit button
+	if ( swfu.getStats().files_queued == 0 )
+		jQuery('#insert-multimedia').attr('disabled', '');
+}
+
+
+// progress and success handlers for single image upload
+
+function uploadLoadedImage() {
+	jQuery('#image-alt').attr('disabled', true);
+	jQuery('#image-url').attr('disabled', true);
+	jQuery('#image-title').attr('disabled', true);
+	jQuery('#image-add').attr('disabled', true);
+}
+
+function fileQueuedImage(fileObj) {
+	jQuery('#flash-upload-ui').append('<div id="image-progress"><p class="filename">' + fileObj.name + '</p><div class="progress"><div class="bar"></div></div></div>');
+}
+
+function uploadProgressImage(fileObj, bytesDone, bytesTotal) {
+	jQuery('#image-progress .bar').width(450*bytesDone/bytesTotal);
+}
+
+function uploadSuccessImage(fileObj, serverData) {
+	if ( serverData.match('media-upload-error') ) {
+		jQuery('#media-upload-error').replaceWith(serverData);
+		jQuery('#image-progress').replaceWith('');
+	}
+	else {
+		jQuery('#media-upload-error').replaceWith('');
+		jQuery('#flash-upload-ui').replaceWith(serverData);
+	}
+}
+
+// wp-specific error handlers
+
+// generic message
+function wpQueueError(message) {
+	jQuery('#media-upload-error').show().text(message);
+}
+
+// file-specific message
+function wpFileError(fileObj, message) {
+	jQuery('#media-upload-error-' + fileObj.id).show().text(message);
+}
+
+function fileQueueError(fileObj, error_code, message)  {
+	// Handle this error separately because we don't want to create a FileProgress element for it.
+	if ( error_code == SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED ) {
+		wpQueueError(swfuploadL10n.queue_limit_exceeded);
+	}
+	else if ( error_code == SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT ) {
+		wpQueueError(swfuploadL10n.file_exceeds_size_limit);
+	}
+	else if ( error_code == SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE ) {
+		wpQueueError(swfuploadL10n.zero_byte_file);
+	}
+	else if ( error_code == SWFUpload.QUEUE_ERROR.INVALID_FILETYPE ) {
+		wpQueueError(swfuploadL10n.invalid_filetype);
+	}
+	else {
+		wpQueueError(swfuploadL10n.default_error);
+	}
+		
+}
+
+function fileQueued(fileObj) {
+	try {
+		var txtFileName = document.getElementById("txtFileName");
+		txtFileName.value = fileObj.name;
+	} catch (e) { }
+
+}
+
+function fileDialogComplete(num_files_queued) {
+	try {
+		if (num_files_queued > 0) {
+			this.startUpload();
+		}
+	} catch (ex) {
+		this.debug(ex);
+	}
+}
+
+function uploadProgress(fileObj, bytesLoaded, bytesTotal) {
+
+	try {
+		var percent = Math.ceil((bytesLoaded / bytesTotal) * 100)
+
+		fileObj.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(fileObj, this.customSettings.progress_target);
+		progress.SetProgress(percent);
+		progress.SetStatus("Uploading...");
+	} catch (e) { }
+}
+
+function uploadSuccess(fileObj, server_data) {
+	try {
+		fileObj.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(fileObj, this.customSettings.progress_target);
+		progress.SetComplete();
+		progress.SetStatus("Complete.");
+		progress.ToggleCancel(false);
+		
+		if (server_data === " ") {
+			this.customSettings.upload_successful = false;
+		} else {
+			this.customSettings.upload_successful = true;
+			document.getElementById("hidFileID").value = server_data;
+		}
+		
+	} catch (e) { }
+}
+
+function uploadComplete(fileObj) {
+	try {
+		if (this.customSettings.upload_successful) {
+			document.getElementById("btnBrowse").disabled = "true";
+			uploadDone();
+		} else {
+			fileObj.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+			var progress = new FileProgress(fileObj, this.customSettings.progress_target);
+			progress.SetError();
+			progress.SetStatus("File rejected");
+			progress.ToggleCancel(false);
+			
+			var txtFileName = document.getElementById("txtFileName");
+			txtFileName.value = "";
+			//validateForm();
+
+			alert("There was a problem with the upload.\nThe server did not accept it.");
+		}
+	} catch (e) {  }
+}
+
+function uploadError(fileObj, error_code, message) {
+		
+		// first the file specific error
+		if ( error_code == SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL ) {
+			wpFileError(fileObj, swfuploadL10n.missing_upload_url);
+		}
+		else if ( error_code == SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED ) {
+			wpFileError(fileObj, swfuploadL10n.upload_limit_exceeded);
+		}
+		else {
+			wpFileError(fileObj, swfuploadL10n.default_error);
+		}
+		
+		// not sure if this is needed
+		fileObj.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(fileObj, this.customSettings.progress_target);
+		progress.SetError();
+		progress.ToggleCancel(false);
+
+		// now the general upload status
+		if ( error_code == SWFUpload.UPLOAD_ERROR.HTTP_ERROR ) {
+			wpQueueError(swfuploadL10n.http_error);
+		}
+		else if ( error_code == SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED ) {
+			wpQueueError(swfuploadL10n.upload_failed);
+		}
+		else if ( error_code == SWFUpload.UPLOAD_ERROR.IO_ERROR ) {
+			wpQueueError(swfuploadL10n.io_error);
+		}
+		else if ( error_code == SWFUpload.UPLOAD_ERROR.SECURITY_ERROR ) {
+			wpQueueError(swfuploadL10n.security_error);
+		}
+		else if ( error_code == SWFUpload.UPLOAD_ERROR.FILE_CANCELLED ) {
+			wpQueueError(swfuploadL10n.security_error);
+		}
+		
+		
+
+}
+
+
+/* ********************************************************
+ *  Utility for displaying the file upload information
+ *  This is not part of SWFUpload, just part of the demo
+ * ******************************************************** */
+function FileProgress(fileObj, target_id) {
+		this.file_progress_id = fileObj.id;
+
+		this.fileProgressElement = document.getElementById(this.file_progress_id);
+		if (!this.fileProgressElement) {
+			this.fileProgressElement = document.createElement("div");
+			this.fileProgressElement.className = "progressContainer";
+			this.fileProgressElement.id = this.file_progress_id;
+
+			var progressCancel = document.createElement("a");
+			progressCancel.className = "progressCancel";
+			progressCancel.href = "#";
+			progressCancel.style.visibility = "hidden";
+			progressCancel.appendChild(document.createTextNode(" "));
+
+			var progressText = document.createElement("div");
+			progressText.className = "progressName";
+			progressText.appendChild(document.createTextNode(fileObj.name));
+
+			var progressBar = document.createElement("div");
+			progressBar.className = "progressBarInProgress";
+
+			var progressStatus = document.createElement("div");
+			progressStatus.className = "progressBarStatus";
+			progressStatus.innerHTML = "&nbsp;";
+
+			this.fileProgressElement.appendChild(progressCancel);
+			this.fileProgressElement.appendChild(progressText);
+			this.fileProgressElement.appendChild(progressStatus);
+			this.fileProgressElement.appendChild(progressBar);
+
+			document.getElementById(target_id).appendChild(this.fileProgressElement);
+
+		}
+
+}
+FileProgress.prototype.SetStart = function() {
+		this.fileProgressElement.className = "progressContainer";
+		this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
+		this.fileProgressElement.childNodes[3].style.width = "";
+}
+
+FileProgress.prototype.SetProgress = function(percentage) {
+		this.fileProgressElement.className = "progressContainer green";
+		this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
+		this.fileProgressElement.childNodes[3].style.width = percentage + "%";
+}
+FileProgress.prototype.SetComplete = function() {
+		this.fileProgressElement.className = "progressContainer blue";
+		this.fileProgressElement.childNodes[3].className = "progressBarComplete";
+		this.fileProgressElement.childNodes[3].style.width = "";
+
+
+}
+FileProgress.prototype.SetError = function() {
+		this.fileProgressElement.className = "progressContainer red";
+		this.fileProgressElement.childNodes[3].className = "progressBarError";
+		this.fileProgressElement.childNodes[3].style.width = "";
+}
+FileProgress.prototype.SetCancelled = function() {
+		this.fileProgressElement.className = "progressContainer";
+		this.fileProgressElement.childNodes[3].className = "progressBarError";
+		this.fileProgressElement.childNodes[3].style.width = "";
+}
+FileProgress.prototype.SetStatus = function(status) {
+		this.fileProgressElement.childNodes[2].innerHTML = status;
+}
+
+FileProgress.prototype.ToggleCancel = function(show, upload_obj) {
+		this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
+		if (upload_obj) {
+			var file_id = this.file_progress_id;
+			this.fileProgressElement.childNodes[0].onclick = function() { upload_obj.cancelUpload(file_id); return false; };
+		}
+}
\ No newline at end of file

Property changes on: wp-includes/js/swfupload/handlers.js
___________________________________________________________________
Name: svn:executable
   + *

Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php	(revision 6646)
+++ wp-includes/script-loader.php	(working copy)
@@ -84,6 +84,27 @@
 		$this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1');
 		$this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20');
 		$this->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array('jquery'), '3.1');
+		$this->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', false, '2.0.2');
+		$this->add( 'swfupload-degrade', '/wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js', array('swfupload'), '2.0.2');
+		$this->add( 'swfupload-queue', '/wp-includes/js/swfupload/plugins/swfupload.queue.js', array('swfupload'), '2.0.2');
+		$this->add( 'swfupload-handlers', '/wp-includes/js/swfupload/handlers.js', array('swfupload'), '2.0.2');
+		// these error messages came from the sample swfupload js, they might need changing.
+		$this->localize( 'swfupload-handlers', 'swfuploadL10n', array(
+				'queue_limit_exceeded' => __('You have attempted to queue too many files.'),
+				'file_exceeds_size_limit' => __('The file you have selected is too big.'),
+				'zero_byte_file' => __('The file you selected is empty.  Please select another file.'),
+				'invalid_filetype' => __('The file you choose is not an allowed file type.'),
+				'default_error' => __('An error occurred in the upload. Please try again later.'),
+				'missing_upload_url' => __('There was a configuration error.  Please contact the server administrator.'),
+				'upload_limit_exceeded' => __('You may only upload 1 file.'),
+				'http_error' => __('HTTP error.'),
+				'upload_failed' => __('Upload failed.'),
+				'io_error' => __('IO error.'),
+				'security_error' => __('Security error.'),
+				'file_cancelled' => __('File cancelled.'),
+				'upload_stopped' => __('Upload stopped.'),
+				
+		) );
 
 		$this->add( 'jquery-ui-tabs', '/wp-includes/js/jquery/ui.tabs.js', array('jquery'), '3' );
 
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 6646)
+++ wp-settings.php	(working copy)
@@ -256,6 +256,7 @@
 require (ABSPATH . WPINC . '/taxonomy.php');
 require (ABSPATH . WPINC . '/update.php');
 require (ABSPATH . WPINC . '/canonical.php');
+require (ABSPATH . WPINC . '/macros.php');
 
 if (strpos($_SERVER['PHP_SELF'], 'install.php') === false) {
 	// Used to guarantee unique hash cookies
Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php	(revision 6646)
+++ wp-admin/includes/template.php	(working copy)
@@ -745,10 +745,15 @@
 	return $size . $units[$power];
 }
 
-function wp_import_upload_form( $action ) {
+function wp_max_upload_size() {
 	$u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) );
 	$p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
-	$bytes = apply_filters( 'import_upload_size_limit', min($u_bytes, $p_bytes), $u_bytes, $p_bytes );
+	$bytes = apply_filters( 'upload_size_limit', min($u_bytes, $p_bytes), $u_bytes, $p_bytes );
+	return $bytes;
+}
+
+function wp_import_upload_form( $action ) {
+	$bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() );
 	$size = wp_convert_bytes_to_hr( $bytes );
 ?>
 <form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo attribute_escape($action) ?>">
Index: wp-admin/includes/media.php
===================================================================
--- wp-admin/includes/media.php	(revision 6646)
+++ wp-admin/includes/media.php	(working copy)
@@ -14,7 +14,8 @@
 	$image_url = attribute_escape( @$values['image-url'] );
 	$image_title = attribute_escape( @$values['image-title'] );
 	$image_align = @$values['image-url'];
-
+	$post_id = $_GET['post_id'];
+	
 ?>
 <div id="media-upload-header">
 <h3>Add Image</h3>
@@ -24,13 +25,55 @@
 	<li class="last"><?php _e('Flickr'); ?></li>
 </ul>
 </div>
-<?php if ($error) { ?>
-	<div id="media-upload-error">
-	<?php echo $error->get_error_message(); ?>
-	</div>
-<?php } ?>
+<div id="media-upload-error">
+<?php if ($error) {
+	echo $error->get_error_message();
+} ?>
+</div>
+<script type="text/javascript">
+<!--
+
+jQuery(document).ready(function(){ 
+	var swfu = new SWFUpload({
+			upload_url : "<?php echo get_option('siteurl').'/wp-admin/async-upload.php'; ?>",
+			flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>",
+			file_post_name: "async-upload",
+			swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available
+			degraded_element_id : "html-upload-ui",   // when swfupload is unavailable
+			//file_types : "*.jpg;*.gif;*.png",
+			file_size_limit : "<?php echo wp_max_upload_size(); ?> B",
+			post_params : {
+				"post_id" : "<?php echo $post_id; ?>",
+				"auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>",
+				"type" : "image",
+			},
+			swfupload_loaded_handler : uploadLoadedImage,
+			upload_progress_handler : uploadProgressImage,
+			upload_success_handler : uploadSuccessImage,
+			upload_error_handler: uploadError,
+			file_queued_handler : fileQueuedImage,
+			file_queue_error_handler : fileQueueError,
+			file_dialog_complete_handler : fileDialogComplete,
+
+			custom_settings : {
+				progressTarget : "flash-upload-ui",
+				cancelButtonId : "btnCancel2"
+			},
+			
+			debug: false,
+		
+		});
+
+	document.getElementById("flash-browse-button").onclick = function () { swfu.selectFile(); };
+});
+//-->
+</script>
 <form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($action_url); ?>" id="image-upload" class="media-upload-form">
-<p><label for="image-file"><?php _e('Choose image'); ?></label>
+<p id="flash-upload-ui">
+	<label for="flash-browse-button"><?php _e('Choose image'); ?></label>
+	<input id="flash-browse-button" type="button" value="<?php _e('Browse'); ?>" />
+	<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label></p>
+<p id="html-upload-ui"><label for="image-file"><?php _e('Choose image'); ?></label>
 	<input type="file" name="image-file" id="image-file" />
 	<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label></p>
 <p><label for="image-alt" class="required"><?php _e('&lt;alt&gt; (required)'); ?></label>
@@ -57,7 +100,7 @@
 	<button name="image-add" id="image-add" class="button-ok" value="1"><?php _e('Add Image'); ?></button>
 	<a href="#" onclick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
 </p>
-	<input type="hidden" name="parent_post_id" value="<?php echo attribute_escape('parent_post_id'); ?>" />
+	<input type="hidden" name="post_id" value="<?php echo attribute_escape($post_id); ?>" />
 	<?php wp_nonce_field( 'inlineuploading' ); ?>
 </form>
 <?php
@@ -69,15 +112,28 @@
 		return new wp_error( 'upload_not_allowed', __('You are not allowed to upload files.') );
 	}
 
-	check_admin_referer('inlineuploading');
-	
 	if ( empty($_POST['image-add']) ) {
 		// no button click, we're just displaying the form
 		wp_iframe( 'image_upload_form', get_option('siteurl') . '/wp-admin/media-upload.php?type=image' );
 	}
 	else {
 		// Add Image button was clicked
-		$id = image_upload_post();
+		check_admin_referer('inlineuploading');
+	
+		// if the async flash uploader was used, the attachment has already been inserted and its ID is passed in post.
+		// otherwise this is a regular form post and we still have to handle the upload and create the attachment.
+		if ( !empty($_POST['attachment_id']) ) {
+			$id = intval($_POST['attachment_id']);
+			// store the title and alt into the attachment post
+			wp_update_post(array(
+				'ID' => $id,
+				'post_title' => $_POST['image-title'],
+				'post_content' => $_POST['image-alt'],
+			));
+		}
+		else {
+			$id = image_upload_post();
+		}
 		
 		// if the input was invalid, redisplay the form with its current values
 		if ( is_wp_error($id) )
@@ -88,6 +144,45 @@
 	}
 }
 
+// this returns html to include in the single image upload form when the async flash upload has finished
+// i.e. show a thumb of the image, and include the attachment id as a hidden input
+function async_image_callback($id) {
+	$thumb_url = wp_get_attachment_thumb_url($id);
+	if ( empty($thumb_url) )
+		$thumb_url = wp_mime_type_icon($id);
+		
+	if ($thumb_url) {
+		$out = '<p><input type="hidden" name="attachment_id" id="attachment_id" value="'.intval($id).'" />'
+			. '<img src="'.wp_get_attachment_thumb_url($id).'" class="pinkynail" /> '
+			. basename(wp_get_attachment_url($id)).'</p>';
+	}
+	else {
+		$out = '<p><input type="hidden" name="attachment_id" id="attachment_id" value="'.intval($id).'" />'
+			. basename(wp_get_attachment_url($id)).'</p>';
+	}
+	
+	$post = get_post($id);
+	$title = addslashes($post->post_title);
+	$alt = addslashes($post->post_content);
+	
+	// populate the input fields with post data (which in turn comes from exif/iptc)
+	$out .= <<<EOF
+<script type="text/javascript">
+<!--
+jQuery('#image-alt').val('{$alt}').attr('disabled', false);
+jQuery('#image-title').val('{$title}').attr('disabled', false);
+jQuery('#image-url').attr('disabled', false);
+jQuery('#image-add').attr('disabled', false);
+-->
+</script>	
+EOF;
+
+	return $out;
+}
+
+add_filter('async_upload_image', 'async_image_callback');
+
+
 function image_send_to_editor($id, $alt, $title, $align, $url='') {
 	
 	$img_src = wp_get_attachment_url($id);
@@ -97,7 +192,7 @@
 	if ( isset($meta['width'], $meta['height']) )
 		$hwstring = ' width="'.intval($meta['width']).'" height="'.intval($meta['height']).'"';
 
-	$html = '<img src="'.attribute_escape($img_src).'" alt="'.attribute_escape($alt).'" title="'.attribute_escape($title).'"'.$hwstring.' class="align-'.attribute_escape($align).'" />';
+	$html = '<img src="'.attribute_escape($img_src).'" rel="attachment wp-att-'.attribute_escape($id).'" alt="'.attribute_escape($alt).'" title="'.attribute_escape($title).'"'.$hwstring.' class="align-'.attribute_escape($align).'" />';
 
 	if ( $url )
 		$html = '<a href="'.attribute_escape($url).'">'.$html.'</a>';
@@ -152,12 +247,51 @@
 	if ( !is_wp_error($id) )
 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
 
+	return $id;		
+}
+
+// this handles the file upload POST itself, creating the attachment post
+function media_handle_upload($file_id, $post_id, $post_data = array()) {
+	$overrides = array('test_form'=>false);
+	$file = wp_handle_upload($_FILES[$file_id], $overrides);
+
+	if ( isset($file['error']) )
+		return new wp_error( 'upload_error', $file['error'] );
+
+	$url = $file['url'];
+	$type = $file['type'];
+	$file = $file['file'];
+	$title = preg_replace('/\.[^.]+$/', '', basename($file));
+	$content = '';
+
+	// use image exif/iptc data for title and caption defaults if possible
+	if ( $image_meta = @wp_read_image_metadata($file) ) {
+		if ( trim($image_meta['title']) )
+			$title = $image_meta['title'];
+		if ( trim($image_meta['caption']) )
+			$content = $image_meta['caption'];
+	}
+
+	// Construct the attachment array
+	$attachment = array_merge( array(
+		'post_mime_type' => $type,
+		'guid' => $url,
+		'post_parent' => $post_id,
+		'post_title' => $title,
+		'post_content' => $content,
+	), $post_data );
+
+	// Save the data
+	$id = wp_insert_attachment($attachment, $file, $post_parent);
+	if ( !is_wp_error($id) ) {
+		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
+	}
+
 	return $id;
 
-	wp_redirect( get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=browse&action=view&ID=$id&post_id=$post_id");
-		
 }
 
+
 // wrap iframe content (produced by $content_func) in a doctype, html head/body etc
 // any additional function args will be passed to content_func
 function wp_iframe($content_func /* ... */) {
@@ -194,10 +328,13 @@
 function media_buttons() { // just a placeholder for now
 	global $post_ID, $temp_ID;
 	$uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
-	$uploading_iframe_src = wp_nonce_url("media-upload.php?type=image&amp;&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
-	$uploading_iframe_src = apply_filters('uploading_iframe_src', $uploading_iframe_src);
+	$image_upload_iframe_src = wp_nonce_url("media-upload.php?type=image&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
+	$image_upload_iframe_src = apply_filters('image_upload_iframe_src', $image_upload_iframe_src);
+	$multimedia_upload_iframe_src = wp_nonce_url("media-upload.php?type=multimedia&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
+	$multimedia_upload_iframe_src = apply_filters('multimedia_upload_iframe_src', $multimedia_upload_iframe_src);
 	$out = <<<EOF
-<a href="{$uploading_iframe_src}&TB_iframe=true&height=500&width=460" class="thickbox">
+<a href="{$multimedia_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox">Multimedia</a>
+<a href="{$image_upload_iframe_src}&TB_iframe=true&height=500&width=460" class="thickbox">
 <img src="./images/media-buttons.gif" alt="" />
 </a>
 EOF;
@@ -225,7 +362,214 @@
 	wp_admin_css('css/media');
 }
 
+add_action('media_upload_multimedia', 'multimedia_upload_handler');
 add_action('media_upload_image', 'image_upload_handler');
 add_action('admin_head_image_upload_form', 'media_admin_css');
 
+function multimedia_upload_handler() {
+	if ( !current_user_can('upload_files') ) {
+		return new wp_error( 'upload_not_allowed', __('You are not allowed to upload files.') );
+	}
+
+	if ( empty($_POST) ) {
+		// no button click, we're just displaying the form
+			wp_iframe( 'multimedia_upload_form' );
+	} elseif ( empty($_POST['upload-button']) ) {
+		// Insert multimedia button was clicked
+		check_admin_referer('multimedia-form');
+
+		if ( !empty($_POST['attachments']) ) foreach ( $_POST['attachments'] as $attachment_id => $attachment ) {
+			$post = $_post = get_post($attachment_id, ARRAY_A);
+			$post['post_content'] = $attachment['post_content'];
+			$post['post_title'] = $attachment['post_title'];
+			if ( $post != $_post )
+				wp_update_post($post);
+
+			if ( $taxonomies = get_object_taxonomies('attachment') ) foreach ( $taxonomies as $t )
+				if ( isset($attachment[$t]) )
+					wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $attachment[$t])), $t, false);
+		}
+
+		media_send_to_editor('[thumbs]');
+	} else {
+		// Upload File button was clicked
+
+		$id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+
+		wp_iframe( 'multimedia_upload_form' );
+	}
+}
+
+function get_multimedia_items( $post_id ) {
+	$attachments = get_children("post_parent=$post_id&post_type=attachment&orderby=\"menu_order ASC, ID ASC\"");
+
+	if ( empty($attachments) )
+		return '';
+
+	foreach ( $attachments as $id => $attachment ) {
+		$output .= "\n<div id='multimedia-item-$id' class='multimedia-item preloaded'><div id='media-upload-error-$id'></div><span class='filename'></span><div class='progress'><div class='bar'></div></div>";
+		$output .= get_multimedia_item($id);
+		$output .= "	<div class='progress clickmask'></div>\n</div>";
+	}
+
+	return $output;
+}
+
+function get_multimedia_item( $attachment_id ) {
+	$thumb_url = wp_get_attachment_thumb_url( $attachment_id );
+	if ( empty($thumb_url) )
+		$thumb_url = wp_mime_type_icon( $attachment_id );
+
+	$title_label = __('Title');
+	$description_label = __('Description');
+	$tags_label = __('Tags');
+
+	$toggle_on = __('Describe &raquo;');
+	$toggle_off = __('Describe &laquo;');
+
+	$post = get_post($attachment_id);
+
+	$filename = basename($post->guid);
+	$title = attribute_escape($post->post_title);
+	$description = attribute_escape($post->post_content);
+	if ( $_tags = get_the_tags($attachment_id) ) {
+		foreach ( $_tags as $tag )
+			$tags[] = $tag->name;
+		$tags = attribute_escape(join(', ', $tags));
+	}
+
+	$delete_href = wp_nonce_url("post.php?action=delete-post&amp;post=$attachment_id", 'delete-post_' . $attachment_id);
+	$delete = __('Delete');
+
+	$item = "
+	<a class='toggle describe-toggle-on' href='#'>$toggle_on</a>
+	<a class='toggle describe-toggle-off' href='#'>$toggle_off</a>
+	<span class='filename new'>$filename</span>
+	<div class='slidetoggle describe'>
+		<img class='thumbnail' src='$thumb_url' alt='' />
+		<fieldset>
+		<p><label for='attachments[$attachment_id][post_title]'>$title_label</label><input type='text' id='attachments[$attachment_id][post_title]' name='attachments[$attachment_id][post_title]' value='$title' /></p>
+		<p><label for='attachments[$attachment_id][post_content]'>$description_label</label><input type='text' id='attachments[$attachment_id][post_content]' name='attachments[$attachment_id][post_content]' value='$description' /></p>
+";
+
+	if ( $taxonomies = get_object_taxonomies('attachment') ) foreach ( $taxonomies as $t ) {
+		$tax = get_taxonomy($t);
+		$t_title = !empty($tax->title) ? $tax->title : $t;
+		if ( false === $terms = get_object_term_cache( $attachment_id, $t ) )
+			$_terms = wp_get_object_terms($attachment_id, $t);
+		if ( $_terms ) {
+			foreach ( $_terms as $term )
+				$terms[] = $term->name;
+			$terms = join(', ', $terms);
+		} else
+			$terms = '';
+		$item .= "<p><label for='attachments[$attachment_id][$t]'>$t_title</label><input type='text' id='attachments[$attachment_id][$t]' name='attachments[$attachment_id][$t]' value='$terms' /></p>\n";
+	}
+
+	$item .= "
+		</fieldset>
+		<p><a id='del$attachment_id' class='delete' href='$delete_href'>$delete</a></p>
+	</div>
+";
+
+	return $item;
+}
+
+function multimedia_upload_form( $error = null ) {
+	$flash_action_url = get_option('siteurl') . '/wp-admin/async-upload.php?type=multimedia';
+	$form_action_url = get_option('siteurl') . '/wp-admin/media-upload.php?type=multimedia';
+
+	$post_id = intval($_REQUEST['post_id']);
+
+?>
+<div id="media-upload-header">
+<h3>Add Images</h3>
+</div>
+	<div id="media-upload-error">
+<?php if ($error) { ?>
+	<?php echo $error->get_error_message(); ?>
+<?php } ?>
+	</div>
+<script type="text/javascript">
+<!--
+jQuery(function($){
+	swfu = new SWFUpload({
+			upload_url : "<?php echo attribute_escape( $flash_action_url ); ?>",
+			flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>",
+			file_post_name: "async-upload",
+			file_types: "*.*",
+			post_params : {
+				"post_id" : "<?php echo $post_id; ?>",
+				"auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>",
+				"type" : "multimedia"
+			},
+			swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available
+			degraded_element_id : "html-upload-ui",   // when swfupload is unavailable
+			//upload_start_handler : uploadStart,
+			upload_progress_handler : uploadProgressMultimedia,
+			//upload_error_handler : uploadError,
+			upload_success_handler : uploadSuccessMultimedia,
+			upload_complete_handler : uploadCompleteMultimedia,
+			file_dialog_start_handler : fileDialogStart,
+			file_queued_handler : fileQueuedMultimedia,
+			file_queue_error_handler : fileQueueError,
+			file_dialog_complete_handler : fileDialogComplete,
+
+			debug: false,
+		});
+	$("#flash-browse-button").bind( "click", function(){swfu.selectFiles();});
+	$("#insert-multimedia").bind( "click", function(){jQuery(this).parents('form').get(0).submit();});
+	$(".multimedia-item.preloaded").each(function(){uploadSuccessMultimedia({id:this.id.replace(/[^0-9]/g, '')},'');jQuery('#insert-multimedia').attr('disabled', '');});
+	$("a.delete").bind('click',function(){$.ajax({url:'admin-ajax.php',type:'post',data:{id:this.id.replace(/del/,''),action:'delete-post',_ajax_nonce:this.href.replace(/^.*wpnonce=/,'')}});$(this).parents(".multimedia-item").eq(0).slideToggle(300, function(){$(this).remove();});return false;});
+});
+//-->
+</script>
+<p id="flash-upload-ui" style="display:none">
+	<input id="flash-browse-button" type="button" value="<?php _e('Choose Files'); ?>" />
+	<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label>
+</p>
+
+<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form">
+
+<div id="html-upload-ui">
+	<p><label for="async-upload"><?php _e('Choose image'); ?></label>
+	<input type="file" name="async-upload" id="async-upload" />
+	<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label>
+	</p>
+	<p>
+	<button id="upload-button" name="upload-button" value="1" class="button-ok"><?php _e('Add Image'); ?></button>
+	<a href="#" onclick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
+	</p>
+	<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
+	<br style="clear:both" />
+</div>
+
+
+
+<div id="multimedia-items">
+
+<?php echo get_multimedia_items($post_id); ?>
+
+</div>
+
+<p class="submit">
+	<a href="#" onclick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
+	<input type="button" class="submit" id="insert-multimedia" value="<?php _e('Insert thumbs into post'); ?>" disabled="disabled" />
+</p>
+
+<?php wp_nonce_field('multimedia-form'); ?>
+
+</form>
+
+<?php
+}
+
+add_action('admin_head_multimedia_upload_form', 'media_admin_css');
+add_filter('async_upload_multimedia', 'get_multimedia_item');
+add_filter('media_upload_multimedia', 'multimedia_upload_handler');
+
+// Any 'attachment' taxonomy will be included in the description input form for the multi uploader
+// Example:
+//register_taxonomy('attachment_people', 'attachment', array('title' => 'People'));
+
 ?>
\ No newline at end of file
Index: wp-admin/async-upload.php
===================================================================
--- wp-admin/async-upload.php	(revision 0)
+++ wp-admin/async-upload.php	(revision 0)
@@ -0,0 +1,28 @@
+<?php
+
+/* This accepts file uploads from swfupload or other asynchronous upload methods.
+
+*/
+
+if ( defined('ABSPATH') )
+	require_once( ABSPATH . 'wp-config.php');
+else
+    require_once('../wp-config.php');
+
+// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
+if ( empty($_COOKIE[AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
+	$_COOKIE[AUTH_COOKIE] = $_REQUEST['auth_cookie'];
+unset($current_user);
+require_once('admin.php');
+
+header('Content-Type: text/plain');
+$id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+if (is_wp_error($id)) {
+	echo '<div id="media-upload-error">'.wp_specialchars($id->get_error_message()).'</div>';
+	exit;
+}
+
+$type = $_REQUEST['type'];
+echo apply_filters("async_upload_{$type}", $id);
+
+?>
\ No newline at end of file
Index: wp-admin/media-upload.php
===================================================================
--- wp-admin/media-upload.php	(revision 6646)
+++ wp-admin/media-upload.php	(working copy)
@@ -1,5 +1,9 @@
 <?php
 require_once('admin.php');
+wp_enqueue_script('swfupload');
+wp_enqueue_script('swfupload-degrade');
+wp_enqueue_script('swfupload-queue');
+wp_enqueue_script('swfupload-handlers');
 
 @header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
 
Index: wp-admin/css/media.css
===================================================================
--- wp-admin/css/media.css	(revision 6646)
+++ wp-admin/css/media.css	(working copy)
@@ -41,6 +41,7 @@
 	display:block;
 	font-weight: bold;
 	margin-bottom: 0.5em;
+	margin: 0 0 0.5em 0;
 }
 
 .media-upload-form label.form-help {
@@ -58,9 +59,11 @@
 }
 
 .media-upload-form fieldset {
+	width: 100%;
 	border: none;
 	text-align: justify;
-	margin-bottom: 1em;
+	margin: 0 0 1em 0;
+	padding: 0;
 }
 
 .media-upload-form button.button-ok {
@@ -83,7 +86,8 @@
 /* specific to the image upload form */
 .media-upload-form fieldset#image-align label {
 	display: inline;
-	padding: 0 28px;
+	padding: 0 0 0 28px;
+	margin: 0 0;
 }
 
 #image-align-none-label {
@@ -100,4 +104,88 @@
 
 #image-align-right-label {
 	background: url(../images/align-right.png) no-repeat center left;
+}
+
+.pinkynail {
+	max-width: 40px;
+	max-height: 40px;
+}
+
+#multimedia-items {
+	border: 1px solid #c0c0c0;
+	border-bottom: none;
+	width: 623px;
+}
+.multimedia-item {
+	border-bottom: 1px solid #d0d0d0;
+	width: 623px;
+	position: relative;
+}
+span.filename {
+	position: absolute;
+	left: 46px;
+	top: 0px;
+	line-height: 36px;
+	z-index: 2;
+}
+.progress {
+	width: 623px;
+	height: 36px;
+}
+.bar {
+	width: 0px;
+	height: 36px;
+	background-color: #e8e8e8;
+	border-right: 3px solid #99d;
+}
+.multimedia-item .thumbnail {
+
+}
+.multimedia-item .pinkynail {
+	position: absolute;
+	top: 3px;
+	left: 3px;
+	max-width: 40px;
+	max-height: 40px;
+}
+.describe {
+	display: none;
+	border-top: 1px solid #d0d0d0;
+	padding: 5px;
+}
+.describe fieldset {
+	width: 470px;
+	float: right;
+}
+.describe img {
+	float: left;
+}
+.describe input[type="text"], .describe textarea {
+	width: 450px;
+}
+.describe label {
+	padding-right: 1em;
+}
+
+a.delete {
+	clear: both;
+}
+.describe-toggle-on, .describe-toggle-off {
+	line-height: 36px;
+	z-index: 2;
+	position: absolute;
+	top: 0px;
+	right: 20px;
+}
+.describe-toggle-off {
+	display: none;
+}
+.clickmask {
+	background: transparent;
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	cursor: pointer;
+	border: none;
+	z-index: 10;
 }
\ No newline at end of file

