Index: wp-includes/css/media-views.css
===================================================================
--- wp-includes/css/media-views.css	(revision 22979)
+++ wp-includes/css/media-views.css	(working copy)
@@ -267,6 +267,10 @@
 	*max-width: 55%; /* IE7 */
 }
 
+.media-sidebar .setting input[type="checkbox"] {
+	margin-top: 10px;
+}
+
 .media-sidebar .setting span,
 .compat-item label span {
 	float: left;
Index: wp-includes/js/media-editor.js
===================================================================
--- wp-includes/js/media-editor.js	(revision 22979)
+++ wp-includes/js/media-editor.js	(working copy)
@@ -189,6 +189,10 @@
 				args.type    = 'image';
 				args.perPage = -1;
 
+				// Mark the `orderby` override attribute.
+				if ( 'rand' === attrs.orderby )
+					attrs._orderbyRandom = true;
+
 				// Map the `orderby` attribute to the corresponding model property.
 				if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) )
 					args.orderby = 'menuOrder';
@@ -232,6 +236,11 @@
 				if ( props.uploadedTo )
 					attrs.id = props.uploadedTo;
 
+				// Check if the gallery is randomly ordered.
+				if ( attrs._orderbyRandom )
+					attrs.orderby = 'rand';
+				delete attrs._orderbyRandom;
+
 				// If the `ids` attribute is set and `orderby` attribute
 				// is the default value, clear it for cleaner output.
 				if ( attrs.ids && 'post__in' === attrs.orderby )
Index: wp-includes/js/media-models.js
===================================================================
--- wp-includes/js/media-models.js	(revision 22979)
+++ wp-includes/js/media-models.js	(working copy)
@@ -832,35 +832,12 @@
 		// If the workflow does not support multiple
 		// selected attachments, reset the selection.
 		add: function( models, options ) {
-			if ( ! this.multiple ) {
-				models = _.isArray( models ) && models.length ? _.first( models ) : models;
-				this.clear( options );
-			}
+			if ( ! this.multiple )
+				this.remove( this.models );
 
 			return Attachments.prototype.add.call( this, models, options );
 		},
 
-		// Removes all models from the selection.
-		clear: function( options ) {
-			this.remove( this.models, options ).single();
-			return this;
-		},
-
-		// Override the selection's reset method.
-		// Always direct items through add and remove,
-		// as we need them to fire.
-		reset: function( models, options ) {
-			this.clear( options ).add( models, options ).single();
-			return this;
-		},
-
-		// Create selection.has, which determines if a model
-		// exists in the collection based on cid and id,
-		// instead of direct comparison.
-		has: function( attachment ) {
-			return !! ( this.getByCid( attachment.cid ) || this.get( attachment.id ) );
-		},
-
 		single: function( model ) {
 			var previous = this._single;
 
@@ -869,7 +846,7 @@
 				this._single = model;
 
 			// If the single model isn't in the selection, remove it.
-			if ( this._single && ! this.has( this._single ) )
+			if ( this._single && ! this.getByCid( this._single.cid ) )
 				delete this._single;
 
 			this._single = this._single || this.last();
Index: wp-includes/js/media-views.js
===================================================================
--- wp-includes/js/media-views.js	(revision 22979)
+++ wp-includes/js/media-views.js	(working copy)
@@ -329,7 +329,7 @@
 		},
 
 		reset: function() {
-			this.get('selection').clear();
+			this.get('selection').reset();
 			this.resetDisplays();
 		},
 
@@ -534,20 +534,32 @@
 		},
 
 		gallerySettings: function() {
-			var library = this.get('library');
+			var library = this.get('library'),
+				browser;
 
 			if ( ! library )
 				return;
 
 			library.gallery = library.gallery || new Backbone.Model();
 
-			this.frame.content.view().sidebar.set({
+			browser = this.frame.content.view();
+
+			browser.sidebar.set({
 				gallery: new media.view.Settings.Gallery({
 					controller: this,
 					model:      library.gallery,
 					priority:   40
 				})
 			});
+
+			browser.toolbar.set( 'reverse', {
+				text:     l10n.reverseOrder,
+				priority: 80,
+
+				click: function() {
+					library.reset( library.toArray().reverse() );
+				}
+			});
 		}
 	});
 
@@ -2497,12 +2509,18 @@
 		buttons: {},
 
 		initialize: function() {
+			var selection = this.options.selection;
+
 			this.controller = this.options.controller;
 
 			this.model.on( 'change:sizes change:uploading change:caption change:title', this.render, this );
 			this.model.on( 'change:percent', this.progress, this );
+
+			// Update the selection.
 			this.model.on( 'add', this.select, this );
 			this.model.on( 'remove', this.deselect, this );
+			if ( selection )
+				selection.on( 'reset', this.updateSelect, this );
 
 			// Update the model's details view.
 			this.model.on( 'selection:single selection:unsingle', this.details, this );
@@ -2510,7 +2528,14 @@
 		},
 
 		dispose: function() {
+			var selection = this.options.selection;
+
+			// Make sure all settings are saved before removing the view.
 			this.updateAll();
+
+			if ( selection )
+				selection.off( null, null, this );
+
 			media.View.prototype.dispose.apply( this, arguments );
 			return this;
 		},
@@ -2549,8 +2574,7 @@
 				delete this.$bar;
 
 			// Check if the model is selected.
-			if ( this.selected() )
-				this.select();
+			this.updateSelect();
 
 			this.views.render();
 			return this;
@@ -2568,7 +2592,7 @@
 			if ( ! selection )
 				return;
 
-			if ( selection.has( model ) ) {
+			if ( this.selected() ) {
 				// If the model is the single model, remove it.
 				// If it is not the same as the single model,
 				// it now becomes the single model.
@@ -2578,10 +2602,14 @@
 			}
 		},
 
+		updateSelect: function() {
+			this[ this.selected() ? 'select' : 'deselect' ]();
+		},
+
 		selected: function() {
 			var selection = this.options.selection;
 			if ( selection )
-				return selection.has( this.model );
+				return !! selection.getByCid( this.model.cid );
 		},
 
 		select: function( model, collection ) {
@@ -3326,7 +3354,7 @@
 
 		clear: function( event ) {
 			event.preventDefault();
-			this.collection.clear();
+			this.collection.reset();
 		}
 	});
 
@@ -3402,7 +3430,7 @@
 
 		clear: function( event ) {
 			event.preventDefault();
-			this.collection.clear();
+			this.collection.reset();
 		}
 	});
 
@@ -3482,6 +3510,10 @@
 			} else if ( $setting.is('input[type="text"], textarea') ) {
 				if ( ! $setting.is(':focus') )
 					$setting.val( value );
+
+			// Handle checkboxes.
+			} else if ( $setting.is('input[type="checkbox"]') ) {
+				$setting.attr( 'checked', !! value );
 			}
 		},
 
@@ -3495,6 +3527,11 @@
 			if ( ! $setting.length )
 				return;
 
+			// Use the correct value for checkboxes.
+			if ( $setting.is('input[type="checkbox"]') )
+				value = $setting[0].checked;
+
+			// Update the corresponding setting.
 			this.model.set( $setting.data('setting'), value );
 
 			// If the setting has a corresponding user setting,
@@ -3564,15 +3601,15 @@
 
 			$input.show();
 
-			if ( 'post' == linkTo ) {
+			if ( 'post' === linkTo ) {
 				$input.val( attachment.get('link') );
-			} else if ( 'file' == linkTo ) {
+			} else if ( 'file' === linkTo ) {
 				$input.val( attachment.get('url') );
 			} else if ( ! this.model.get('linkUrl') ) {
 				$input.val('http://');
 			}
 
-			$input.prop('readonly', 'custom' !== linkTo);
+			$input.prop( 'readonly', 'custom' !== linkTo );
 
 			// If the input is visible, focus and select its contents.
 			if ( $input.is(':visible') )
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 22979)
+++ wp-includes/media.php	(working copy)
@@ -670,8 +670,9 @@
 	$instance++;
 
 	if ( ! empty( $attr['ids'] ) ) {
-		// 'ids' is explicitly ordered
-		$attr['orderby'] = 'post__in';
+		// 'ids' is explicitly ordered, unless you specify otherwise.
+		if ( empty( $attr['orderby'] ) )
+			$attr['orderby'] = 'post__in';
 		$attr['include'] = $attr['ids'];
 	}
 
@@ -1489,6 +1490,7 @@
 		'updateGallery'      => __( 'Update gallery' ),
 		'continueEditing'    => __( 'Continue editing' ),
 		'addToGallery'       => __( 'Add to gallery' ),
+		'reverseOrder'       => __( 'Reverse order' ),
 	);
 
 	$settings = apply_filters( 'media_view_settings', $settings, $post );
@@ -1865,6 +1867,11 @@
 				<?php endfor; ?>
 			</select>
 		</label>
+
+		<label class="setting">
+			<span><?php _e('Random'); ?></span>
+			<input type="checkbox" data-setting="_orderbyRandom" />
+		</label>
 	</script>
 
 	<script type="text/html" id="tmpl-embed-link-settings">
