Index: src/wp-admin/css/customize-controls.css
===================================================================
--- src/wp-admin/css/customize-controls.css	(revision 32825)
+++ src/wp-admin/css/customize-controls.css	(working copy)
@@ -762,6 +762,7 @@
 .customize-control-upload .current,
 .customize-control-image .current,
 .customize-control-background .current,
+.customize-control-cropimage .current,
 .customize-control-header .current {
 	margin-bottom: 8px;
 }
@@ -797,6 +798,9 @@
 .customize-control-background .remove-button,
 .customize-control-background .default-button,
 .customize-control-background .upload-button,
+.customize-control-cropimage .remove-button,
+.customize-control-cropimage .default-button,
+.customize-control-cropimage .upload-button,
 .customize-control-header button.new,
 .customize-control-header button.remove {
 	white-space: normal;
@@ -808,6 +812,7 @@
 .customize-control-upload .current .container,
 .customize-control-image .current .container,
 .customize-control-background .current .container,
+.customize-control-cropimage .current .container,
 .customize-control-header .current .container {
 	overflow: hidden;
 	-webkit-border-radius: 2px;
@@ -819,6 +824,7 @@
 .customize-control-media .current .container,
 .customize-control-upload .current .container,
 .customize-control-background .current .container,
+.customize-control-cropimage .current .container,
 .customize-control-image .current .container {
 	min-height: 40px;
 }
@@ -827,6 +833,7 @@
 .customize-control-upload .placeholder,
 .customize-control-image .placeholder,
 .customize-control-background .placeholder,
+.customize-control-cropimage .placeholder,
 .customize-control-header .placeholder {
 	width: 100%;
 	position: relative;
@@ -838,6 +845,7 @@
 .customize-control-upload .inner,
 .customize-control-image .inner,
 .customize-control-background .inner,
+.customize-control-cropimage .inner,
 .customize-control-header .inner {
 	display: none;
 	position: absolute;
@@ -851,6 +859,7 @@
 .customize-control-media .inner,
 .customize-control-upload .inner,
 .customize-control-background .inner,
+.customize-control-cropimage .inner,
 .customize-control-image .inner {
 	display: block;
 	min-height: 40px;
@@ -860,6 +869,7 @@
 .customize-control-upload .inner,
 .customize-control-image .inner,
 .customize-control-background .inner,
+.customize-control-cropimage .inner,
 .customize-control-header .inner,
 .customize-control-header .inner .dashicons {
 	line-height: 20px;
@@ -963,6 +973,7 @@
 .customize-control-upload .actions,
 .customize-control-image .actions,
 .customize-control-background .actions,
+.customize-control-cropimage .actions,
 .customize-control-header .actions {
 	margin-bottom: 32px;
 }
@@ -981,6 +992,7 @@
 .customize-control-upload img,
 .customize-control-image img,
 .customize-control-background img,
+.customize-control-cropimage img,
 .customize-control-header img {
 	width: 100%;
 	-webkit-border-radius: 2px;
@@ -995,6 +1007,8 @@
 .customize-control-image .default-button,
 .customize-control-background .remove-button,
 .customize-control-background .default-button,
+.customize-control-cropimage .remove-button,
+.customize-control-cropimage .default-button,
 .customize-control-header .remove {
 	float: left;
 	margin-right: 3px;
@@ -1004,6 +1018,7 @@
 .customize-control-upload .upload-button,
 .customize-control-image .upload-button,
 .customize-control-background .upload-button,
+.customize-control-cropimage .upload-button,
 .customize-control-header .new {
 	float: right;
 }
Index: src/wp-admin/js/customize-controls.js
===================================================================
--- src/wp-admin/js/customize-controls.js	(revision 32825)
+++ src/wp-admin/js/customize-controls.js	(working copy)
@@ -1840,69 +1840,84 @@
 	 * @augments wp.customize.Control
 	 * @augments wp.customize.Class
 	 */
-	api.HeaderControl = api.Control.extend({
+	api.CropControl = api.UploadControl.extend({
+		/**
+		 * When the control's DOM structure is ready,
+		 * set up internal event bindings.
+		 */
 		ready: function() {
-			this.btnRemove = $('#customize-control-header_image .actions .remove');
-			this.btnNew    = $('#customize-control-header_image .actions .new');
+			var control = this;
 
-			_.bindAll(this, 'openMedia', 'removeImage');
+			api.UploadControl.prototype.ready.apply( this, arguments );
+		},
 
-			this.btnNew.on( 'click', this.openMedia );
-			this.btnRemove.on( 'click', this.removeImage );
+		/**
+		 * Open the media modal.
+		 */
+		openFrame: function( event ) {
+			if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
+				return;
+			}
 
-			api.HeaderTool.currentHeader = this.getInitialHeaderImage();
+			if ( this.frame ) {
+				this.frame.setState('library');
+			}
 
-			new api.HeaderTool.CurrentView({
-				model: api.HeaderTool.currentHeader,
-				el: '#customize-control-header_image .current .container'
-			});
+			api.UploadControl.prototype.openFrame.call( this, event );
+		},
 
-			new api.HeaderTool.ChoiceListView({
-				collection: api.HeaderTool.UploadsList = new api.HeaderTool.ChoiceList(),
-				el: '#customize-control-header_image .choices .uploaded .list'
-			});
+		/**
+		 * Create a media modal select frame, and store it so the instance can be reused when needed.
+		 */
+		initFrame: function() {
+			var l10n = _wpMediaViewsL10n;
 
-			new api.HeaderTool.ChoiceListView({
-				collection: api.HeaderTool.DefaultsList = new api.HeaderTool.DefaultsList(),
-				el: '#customize-control-header_image .choices .default .list'
+			this.frame = wp.media({
+				button: {
+					text: l10n.selectAndCrop,
+					close: false
+				},
+				states: [
+					new wp.media.controller.Library({
+						title:     this.params.button_labels.frame_title,
+						library:   wp.media.query({ type: 'image' }),
+						multiple:  false,
+						date:      false,
+						priority:  20,
+						suggestedWidth: this.params.width,
+						suggestedHeight: this.params.height
+					}),
+					new wp.media.controller.Cropper({
+						imgSelectOptions: this.calculateImageSelectOptions,
+						control: this
+					})
+				]
 			});
 
-			api.HeaderTool.combinedList = api.HeaderTool.CombinedList = new api.HeaderTool.CombinedList([
-				api.HeaderTool.UploadsList,
-				api.HeaderTool.DefaultsList
-			]);
+			this.frame.on('select', this.select, this);
+			this.frame.on('cropped', this.onCropped, this);
+			this.frame.on('skippedcrop', this.onSkippedCrop, this);
 		},
 
 		/**
-		 * Returns a new instance of api.HeaderTool.ImageModel based on the currently
-		 * saved header image (if any).
+		 * After an image is selected in the media modal,
+		 * switch to the cropper state.
+		 */
+		select: function() {
+			this.frame.setState('cropper');
+		},
+
+		/**
+		 * After the image has been cropped, apply the cropped image data to the setting.
 		 *
-		 * @since 4.2.0
-		 *
-		 * @returns {Object} Options
+		 * @param {object} croppedImage Cropped attachment data.
 		 */
-		getInitialHeaderImage: function() {
-			if ( ! api.get().header_image || ! api.get().header_image_data || _.contains( [ 'remove-header', 'random-default-image', 'random-uploaded-image' ], api.get().header_image ) ) {
-				return new api.HeaderTool.ImageModel();
-			}
-
-			// Get the matching uploaded image object.
-			var currentHeaderObject = _.find( _wpCustomizeHeader.uploads, function( imageObj ) {
-				return ( imageObj.attachment_id === api.get().header_image_data.attachment_id );
-			} );
-			// Fall back to raw current header image.
-			if ( ! currentHeaderObject ) {
-				currentHeaderObject = {
-					url: api.get().header_image,
-					thumbnail_url: api.get().header_image,
-					attachment_id: api.get().header_image_data.attachment_id
-				};
-			}
-
-			return new api.HeaderTool.ImageModel({
-				header: currentHeaderObject,
-				choice: currentHeaderObject.url.split( '/' ).pop()
-			});
+		onCropped: function(croppedImage) {
+			var url = croppedImage.post_content,
+				attachmentId = croppedImage.attachment_id,
+				w = croppedImage.width,
+				h = croppedImage.height;
+			this.setImageFromURL(url, attachmentId, w, h);
 		},
 
 		/**
@@ -1915,10 +1930,11 @@
 		 * @returns {Object} Options
 		 */
 		calculateImageSelectOptions: function(attachment, controller) {
-			var xInit = parseInt(_wpCustomizeHeader.data.width, 10),
-				yInit = parseInt(_wpCustomizeHeader.data.height, 10),
-				flexWidth = !! parseInt(_wpCustomizeHeader.data['flex-width'], 10),
-				flexHeight = !! parseInt(_wpCustomizeHeader.data['flex-height'], 10),
+			var control = controller.get('control');
+			var xInit = parseInt(control.params.width, 10),
+				yInit = parseInt(control.params.height, 10),
+				flexWidth = !! parseInt(control.params.flex_width, 10),
+				flexHeight = !! parseInt(control.params.flex_height, 10),
 				ratio, xImg, yImg, realHeight, realWidth,
 				imgSelectOptions;
 
@@ -1925,8 +1941,8 @@
 			realWidth = attachment.get('width');
 			realHeight = attachment.get('height');
 
-			this.headerImage = new api.HeaderTool.ImageModel();
-			this.headerImage.set({
+			this.image = new api.CropTool.ImageModel();
+			this.image.set({
 				themeWidth: xInit,
 				themeHeight: yInit,
 				themeFlexWidth: flexWidth,
@@ -1935,7 +1951,7 @@
 				imageHeight: realHeight
 			});
 
-			controller.set( 'canSkipCrop', ! this.headerImage.shouldBeCropped() );
+			controller.set( 'canSkipCrop', ! this.image.shouldBeCropped() );
 
 			ratio = xInit / yInit;
 			xImg = realWidth;
@@ -1976,68 +1992,6 @@
 		},
 
 		/**
-		 * Sets up and opens the Media Manager in order to select an image.
-		 * Depending on both the size of the image and the properties of the
-		 * current theme, a cropping step after selection may be required or
-		 * skippable.
-		 *
-		 * @param {event} event
-		 */
-		openMedia: function(event) {
-			var l10n = _wpMediaViewsL10n;
-
-			event.preventDefault();
-
-			this.frame = wp.media({
-				button: {
-					text: l10n.selectAndCrop,
-					close: false
-				},
-				states: [
-					new wp.media.controller.Library({
-						title:     l10n.chooseImage,
-						library:   wp.media.query({ type: 'image' }),
-						multiple:  false,
-						date:      false,
-						priority:  20,
-						suggestedWidth: _wpCustomizeHeader.data.width,
-						suggestedHeight: _wpCustomizeHeader.data.height
-					}),
-					new wp.media.controller.Cropper({
-						imgSelectOptions: this.calculateImageSelectOptions
-					})
-				]
-			});
-
-			this.frame.on('select', this.onSelect, this);
-			this.frame.on('cropped', this.onCropped, this);
-			this.frame.on('skippedcrop', this.onSkippedCrop, this);
-
-			this.frame.open();
-		},
-
-		/**
-		 * After an image is selected in the media modal,
-		 * switch to the cropper state.
-		 */
-		onSelect: function() {
-			this.frame.setState('cropper');
-		},
-
-		/**
-		 * After the image has been cropped, apply the cropped image data to the setting.
-		 *
-		 * @param {object} croppedImage Cropped attachment data.
-		 */
-		onCropped: function(croppedImage) {
-			var url = croppedImage.post_content,
-				attachmentId = croppedImage.attachment_id,
-				w = croppedImage.width,
-				h = croppedImage.height;
-			this.setImageFromURL(url, attachmentId, w, h);
-		},
-
-		/**
 		 * If cropping was skipped, apply the image data directly to the setting.
 		 *
 		 * @param {object} selection
@@ -2088,15 +2042,15 @@
 			choice.importImage();
 		},
 
-		/**
-		 * Triggers the necessary events to deselect an image which was set as
-		 * the currently selected one.
-		 */
-		removeImage: function() {
-			api.HeaderTool.currentHeader.trigger('hide');
-			api.HeaderTool.CombinedList.trigger('control:removeImage');
-		}
+	});
 
+	/**
+	 * @class
+	 * @augments wp.customize.Control
+	 * @augments wp.customize.Class
+	 */
+	api.HeaderControl = api.CropControl.extend({
+
 	});
 
 	/**
@@ -2699,6 +2653,7 @@
 		media:      api.MediaControl,
 		upload:     api.UploadControl,
 		image:      api.ImageControl,
+		cropimage:  api.CropControl,
 		header:     api.HeaderControl,
 		background: api.BackgroundControl,
 		theme:      api.ThemeControl
Index: src/wp-includes/class-wp-customize-control.php
===================================================================
--- src/wp-includes/class-wp-customize-control.php	(revision 32825)
+++ src/wp-includes/class-wp-customize-control.php	(working copy)
@@ -997,32 +997,32 @@
 }
 
 /**
- * Customize Header Image Control class.
+ * Customize Cropped Image Control class.
  *
- * @since 3.4.0
+ * @since 4.3.0
  *
  * @see WP_Customize_Image_Control
  */
-class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
-	public $type = 'header';
-	public $uploaded_headers;
-	public $default_headers;
+class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {
+	public $type = 'cropimage';
 
+	protected $width  = 150;
+	protected $height = 150;
+	protected $flex_width  = false;
+	protected $flex_height = false;
+	protected $localized_name;
+	protected $current_title = '';
+
 	/**
+	 * Constructor.
+	 *
+	 * @since 4.3.0
+	 * @uses WP_Customize_Image_Control::__construct()
+	 *
 	 * @param WP_Customize_Manager $manager
 	 */
-	public function __construct( $manager ) {
-		parent::__construct( $manager, 'header_image', array(
-			'label'    => __( 'Header Image' ),
-			'settings' => array(
-				'default' => 'header_image',
-				'data'    => 'header_image_data',
-			),
-			'section'  => 'header_image',
-			'removed'  => 'remove-header',
-			'get_url'  => 'get_header_image',
-		) );
-
+	public function __construct( $manager, $id, $args ) {
+		parent::__construct( $manager, $id, $args );
 	}
 
 	/**
@@ -1029,28 +1029,61 @@
 	 * @access public
 	 */
 	public function enqueue() {
-		wp_enqueue_media();
 		wp_enqueue_script( 'customize-views' );
 
-		$this->prepare_control();
+		parent::enqueue();
+	}
 
-		wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
-			'data' => array(
-				'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
-				'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
-				'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
-				'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
-				'currentImgSrc' => $this->get_current_image_src(),
+	/**
+	 * Refresh the parameters passed to the JavaScript via JSON.
+	 *
+	 * @since 4.3.0
+	 * @access public
+	 * @uses WP_Customize_Image_Control::to_json()
+	 *
+	 * @see WP_Customize_Control::to_json()
+	 */
+	public function to_json() {
+		parent::to_json();
+
+		$this->json['width']       = absint( $this->width );
+		$this->json['height']      = absint( $this->height );
+		$this->json['flex_width']  = absint( $this->flex_width );
+		$this->json['flex_height'] = absint( $this->flex_height );
+	}
+
+}
+
+/**
+ * Customize Header Image Control class.
+ *
+ * @since 3.4.0
+ *
+ * @see WP_Customize_Cropped_Image_Control
+ */
+class WP_Customize_Header_Image_Control extends WP_Customize_Cropped_Image_Control {
+	public $type = 'header';
+
+	/**
+	 * @param WP_Customize_Manager $manager
+	 */
+	public function __construct( $manager ) {
+		parent::__construct( $manager, 'header_image', array(
+			'label'         => __( 'Header Image' ),
+			'current_title' => __( 'Current header' ),
+			'settings' => array(
+				'default' => 'header_image',
+				'data'    => 'header_image_data',
 			),
-			'nonces' => array(
-				'add' => wp_create_nonce( 'header-add' ),
-				'remove' => wp_create_nonce( 'header-remove' ),
-			),
-			'uploads' => $this->uploaded_headers,
-			'defaults' => $this->default_headers
+			'section'       => 'header_image',
+			'removed'       => 'remove-header',
 		) );
 
-		parent::enqueue();
+		$this->width  = get_theme_support( 'custom-header', 'width' );
+		$this->height = get_theme_support( 'custom-header', 'height' );
+		$this->flex_width  = get_theme_support( 'custom-header', 'flex-width' );
+		$this->flex_height = get_theme_support( 'custom-header', 'flex-height' );
+		$this->localized_name = '_wpCustomizeHeader';
 	}
 
 	/**
@@ -1059,6 +1092,7 @@
 	 */
 	public function prepare_control() {
 		global $custom_image_header;
+
 		if ( empty( $custom_image_header ) ) {
 			return;
 		}
@@ -1065,8 +1099,8 @@
 
 		// Process default headers and uploaded headers.
 		$custom_image_header->process_default_headers();
-		$this->default_headers = $custom_image_header->get_default_header_images();
-		$this->uploaded_headers = $custom_image_header->get_uploaded_header_images();
+		$this->default_images  = $custom_image_header->get_default_header_images();
+		$this->uploaded_images = $custom_image_header->get_uploaded_header_images();
 	}
 
 	/**
@@ -1100,109 +1134,16 @@
 
 			<# } #>
 		</script>
-
-		<script type="text/template" id="tmpl-header-current">
-			<# if (data.choice) { #>
-				<# if (data.random) { #>
-
-			<div class="placeholder">
-				<div class="inner">
-					<span><span class="dashicons dashicons-randomize dice"></span>
-					<# if ( data.type === 'uploaded' ) { #>
-						<?php _e( 'Randomizing uploaded headers' ); ?>
-					<# } else if ( data.type === 'default' ) { #>
-						<?php _e( 'Randomizing suggested headers' ); ?>
-					<# } #>
-					</span>
-				</div>
-			</div>
-
-				<# } else { #>
-
-			<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>
-
-				<# } #>
-			<# } else { #>
-
-			<div class="placeholder">
-				<div class="inner">
-					<span>
-						<?php _e( 'No image set' ); ?>
-					</span>
-				</div>
-			</div>
-
-			<# } #>
-		</script>
 		<?php
 	}
 
 	/**
-	 * @return string|void
-	 */
-	public function get_current_image_src() {
-		$src = $this->value();
-		if ( isset( $this->get_url ) ) {
-			$src = call_user_func( $this->get_url, $src );
-			return $src;
-		}
-	}
-
-	/**
 	 * @access public
 	 */
 	public function render_content() {
 		$this->print_header_image_template();
-		$visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
-		$width = absint( get_theme_support( 'custom-header', 'width' ) );
-		$height = absint( get_theme_support( 'custom-header', 'height' ) );
-		?>
 
-
-		<div class="customize-control-content">
-			<p class="customizer-section-intro">
-				<?php
-				if ( $width && $height ) {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
-				} elseif ( $width ) {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header width of <strong>%s</strong> pixels.' ), $width );
-				} else {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header height of <strong>%s</strong> pixels.' ), $height );
-				}
-				?>
-			</p>
-			<div class="current">
-				<span class="customize-control-title">
-					<?php _e( 'Current header' ); ?>
-				</span>
-				<div class="container">
-				</div>
-			</div>
-			<div class="actions">
-				<?php /* translators: Hide as in hide header image via the Customizer */ ?>
-				<button type="button"<?php echo $visibility ?> class="button remove"><?php _ex( 'Hide image', 'custom header' ); ?></button>
-				<?php /* translators: New as in add new header image via the Customizer */ ?>
-				<button type="button" class="button new"><?php _ex( 'Add new image', 'header image' ); ?></button>
-				<div style="clear:both"></div>
-			</div>
-			<div class="choices">
-				<span class="customize-control-title header-previously-uploaded">
-					<?php _ex( 'Previously uploaded', 'custom headers' ); ?>
-				</span>
-				<div class="uploaded">
-					<div class="list">
-					</div>
-				</div>
-				<span class="customize-control-title header-default">
-					<?php _ex( 'Suggested', 'custom headers' ); ?>
-				</span>
-				<div class="default">
-					<div class="list">
-					</div>
-				</div>
-			</div>
-		</div>
-		<?php
+		parent::render_content();
 	}
 }
 
Index: src/wp-includes/class-wp-customize-manager.php
===================================================================
--- src/wp-includes/class-wp-customize-manager.php	(revision 32825)
+++ src/wp-includes/class-wp-customize-manager.php	(working copy)
@@ -1278,6 +1278,7 @@
 		$this->register_control_type( 'WP_Customize_Upload_Control' );
 		$this->register_control_type( 'WP_Customize_Image_Control' );
 		$this->register_control_type( 'WP_Customize_Background_Image_Control' );
+		$this->register_control_type( 'WP_Customize_Cropped_Image_Control' );
 		$this->register_control_type( 'WP_Customize_Theme_Control' );
 
 		/* Themes */
Index: src/wp-includes/class-wp-customize-nav-menus.php
===================================================================
--- src/wp-includes/class-wp-customize-nav-menus.php	(revision 32825)
+++ src/wp-includes/class-wp-customize-nav-menus.php	(working copy)
@@ -403,37 +403,34 @@
 			'description' => $description,
 		) );
 
-		// @todo if ( ! $menus ) : make a "default" menu
-		if ( $menus ) {
-			$choices = array( '0' => __( '&mdash; Select &mdash;' ) );
-			foreach ( $menus as $menu ) {
-				$choices[ $menu->term_id ] = wp_html_excerpt( $menu->name, 40, '&hellip;' );
-			}
+		$choices = array( '0' => __( '&mdash; Select &mdash;' ) );
+		foreach ( $menus as $menu ) {
+			$choices[ $menu->term_id ] = wp_html_excerpt( $menu->name, 40, '&hellip;' );
+		}
 
-			foreach ( $locations as $location => $description ) {
-				$setting_id = "nav_menu_locations[{$location}]";
+		foreach ( $locations as $location => $description ) {
+			$setting_id = "nav_menu_locations[{$location}]";
 
-				$setting = $this->manager->get_setting( $setting_id );
-				if ( $setting ) {
-					$setting->transport = 'postMessage';
-					remove_filter( "customize_sanitize_{$setting_id}", 'absint' );
-					add_filter( "customize_sanitize_{$setting_id}", array( $this, 'intval_base10' ) );
-				} else {
-					$this->manager->add_setting( $setting_id, array(
-						'sanitize_callback' => array( $this, 'intval_base10' ),
-						'theme_supports'    => 'menus',
-						'type'              => 'theme_mod',
-						'transport'         => 'postMessage',
-					) );
-				}
+			$setting = $this->manager->get_setting( $setting_id );
+			if ( $setting ) {
+				$setting->transport = 'postMessage';
+				remove_filter( "customize_sanitize_{$setting_id}", 'absint' );
+				add_filter( "customize_sanitize_{$setting_id}", array( $this, 'intval_base10' ) );
+			} else {
+				$this->manager->add_setting( $setting_id, array(
+					'sanitize_callback' => array( $this, 'intval_base10' ),
+					'theme_supports'    => 'menus',
+					'type'              => 'theme_mod',
+					'transport'         => 'postMessage',
+				) );
+			}
 
-				$this->manager->add_control( new WP_Customize_Nav_Menu_Location_Control( $this->manager, $setting_id, array(
-					'label'       => $description,
-					'location_id' => $location,
-					'section'     => 'menu_locations',
-					'choices'     => $choices,
-				) ) );
-			}
+			$this->manager->add_control( new WP_Customize_Nav_Menu_Location_Control( $this->manager, $setting_id, array(
+				'label'       => $description,
+				'location_id' => $location,
+				'section'     => 'menu_locations',
+				'choices'     => $choices,
+			) ) );
 		}
 
 		// Register each menu as a Customizer section, and add each menu item to each menu.
Index: src/wp-includes/js/customize-models.js
===================================================================
--- src/wp-includes/js/customize-models.js	(revision 32825)
+++ src/wp-includes/js/customize-models.js	(working copy)
@@ -1,11 +1,11 @@
 /* globals _wpCustomizeHeader, _ */
 (function( $, wp ) {
 	var api = wp.customize;
-	api.HeaderTool = {};
+	api.CropTool = api.HeaderTool = {};
 
 
 	/**
-	 * wp.customize.HeaderTool.ImageModel
+	 * wp.customize.CropTool.ImageModel
 	 *
 	 * A header image. This is where saves via the Customizer API are
 	 * abstracted away, plus our own AJAX calls to add images to and remove
@@ -16,7 +16,7 @@
 	 * @constructor
 	 * @augments Backbone.Model
 	 */
-	api.HeaderTool.ImageModel = Backbone.Model.extend({
+	api.CropTool.ImageModel = Backbone.Model.extend({
 		defaults: function() {
 			return {
 				header: {
@@ -129,7 +129,7 @@
 	 * @augments Backbone.Collection
 	 */
 	api.HeaderTool.ChoiceList = Backbone.Collection.extend({
-		model: api.HeaderTool.ImageModel,
+		model: api.CropTool.ImageModel,
 
 		// Ordered from most recently used to least
 		comparator: function(model) {
Index: src/wp-includes/js/customize-views.js
===================================================================
--- src/wp-includes/js/customize-views.js	(revision 32825)
+++ src/wp-includes/js/customize-views.js	(working copy)
@@ -16,7 +16,7 @@
 	 * @augments wp.Backbone.View
 	 */
 	api.HeaderTool.CurrentView = wp.Backbone.View.extend({
-		template: wp.template('header-current'),
+		template: wp.template('cropped-current'),
 
 		initialize: function() {
 			this.listenTo(this.model, 'change', this.render);
@@ -86,7 +86,7 @@
 	 * Represents a choosable header image, be it user-uploaded,
 	 * theme-suggested or a special Randomize choice.
 	 *
-	 * Takes a wp.customize.HeaderTool.ImageModel.
+	 * Takes a wp.customize.CropTool.ImageModel.
 	 *
 	 * Manually changes model wp.customize.HeaderTool.currentHeader via the
 	 * `select` method.
