Index: src/wp-admin/js/image-edit.js
===================================================================
--- src/wp-admin/js/image-edit.js	(revision 27233)
+++ src/wp-admin/js/image-edit.js	(working copy)
@@ -5,6 +5,7 @@
 	iasapi : {},
 	hold : {},
 	postid : '',
+	_view : {},
 
 	intval : function(f) {
 		return f | 0;
@@ -287,7 +288,9 @@
 		});
 	},
 
-	open : function(postid, nonce) {
+	open : function( postid, nonce, view ) {
+		this._view = view;
+
 		var data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid),
 			btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner');
 
@@ -319,8 +322,10 @@
 	},
 
 	initCrop : function(postid, image, parent) {
-		var t = this, selW = $('#imgedit-sel-width-' + postid),
-			selH = $('#imgedit-sel-height-' + postid);
+		var t = this,
+			selW = $('#imgedit-sel-width-' + postid),
+			selH = $('#imgedit-sel-height-' + postid),
+			$img;
 
 		t.iasapi = $(image).imgAreaSelect({
 			parent: parent,
@@ -330,7 +335,13 @@
 			minWidth: 3,
 			minHeight: 3,
 
-			onInit: function() {
+			onInit: function( img ) {
+				// Ensure that the imgareaselect wrapper elements are position:absolute
+				// (even if we're in a position:fixed modal)
+				$img = $( img );
+				$img.next().css( 'position', 'absolute' )
+					.nextAll( '.imgareaselect-outer' ).css( 'position', 'absolute' );
+
 				parent.children().mousedown(function(e){
 					var ratio = false, sel, defRatio;
 
@@ -397,10 +408,22 @@
 
 		this.iasapi = {};
 		this.hold = {};
-		$('#image-editor-' + postid).fadeOut('fast', function() {
-			$('#media-head-' + postid).fadeIn('fast');
-			$(this).empty();
-		});
+
+		// If we've loaded the editor in the context of a Media Modal, then switch to the previous view,
+		// whatever that might have been.
+		if ( this._view && 'object' === typeof this._view ){
+			this._view.cancel();
+		}
+
+		// In case we are not accessing the image editor in the context of a View, close the editor the old-skool way
+		else {
+			$('#image-editor-' + postid).fadeOut('fast', function() {
+				$('#media-head-' + postid).fadeIn('fast');
+				$(this).empty();
+			});
+		}
+
+
 	},
 
 	notsaved : function(postid) {
Index: src/wp-includes/js/media-editor.js
===================================================================
--- src/wp-includes/js/media-editor.js	(revision 27233)
+++ src/wp-includes/js/media-editor.js	(working copy)
@@ -613,7 +613,7 @@
 
 			this._frame = wp.media({
 				state: 'featured-image',
-				states: [ new wp.media.controller.FeaturedImage() ]
+				states: [ new wp.media.controller.FeaturedImage() , new wp.media.controller.EditImage() ]
 			});
 
 			this._frame.on( 'toolbar:create:featured-image', function( toolbar ) {
@@ -625,6 +625,17 @@
 				});
 			}, this._frame );
 
+			this._frame.on( 'content:render:edit-image', function() {
+				var selection = this.state('featured-image').get('selection'),
+					view = new wp.media.view.EditImage( { model: selection.single(), controller: this } ).render();
+
+				this.content.set( view );
+
+				// after bringing in the frame, load the actual editor via an ajax call
+				view.loadEditor();
+
+			}, this._frame );
+
 			this._frame.state('featured-image').on( 'select', this.select );
 			return this._frame;
 		},
Index: src/wp-includes/js/media-views.js
===================================================================
--- src/wp-includes/js/media-views.js	(revision 27233)
+++ src/wp-includes/js/media-views.js	(working copy)
@@ -957,7 +957,7 @@
 			toolbar:    'featured-image',
 			title:      l10n.setFeaturedImageTitle,
 			priority:   60,
-			syncSelection: false
+			syncSelection: true
 		}, media.controller.Library.prototype.defaults ),
 
 		initialize: function() {
@@ -1089,6 +1089,52 @@
 	});
 
 	/**
+	 * wp.media.controller.EditImage
+	 *
+	 * @constructor
+	 * @augments wp.media.controller.State
+	 * @augments Backbone.Model
+	 */
+	media.controller.EditImage = media.controller.State.extend({
+		defaults: {
+			id: 'edit-image',
+			url: '',
+			menu: false,
+			content: 'edit-image',
+			syncSelection: true
+		},
+
+		activate: function() {
+			if ( ! this.get('selection') ) {
+				this.set( 'selection', new media.model.Selection() );
+			}
+			this.syncSelection();
+		},
+
+		syncSelection: function() {
+			var selection = this.get('selection'),
+				manager = this.frame._selection;
+
+			if ( ! this.get('syncSelection') || ! manager || ! selection ) {
+				return;
+			}
+
+			// If the selection supports multiple items, validate the stored
+			// attachments based on the new selection's conditions. Record
+			// the attachments that are not included; we'll maintain a
+			// reference to those. Other attachments are considered in flux.
+			if ( selection.multiple ) {
+				selection.reset( [], { silent: true });
+				selection.validateAll( manager.attachments );
+				manager.difference = _.difference( manager.attachments.models, selection.models );
+			}
+
+			// Sync the selection's single item with the master.
+			selection.single( manager.single );
+		}
+	});
+
+	/**
 	 * wp.media.controller.Embed
 	 *
 	 * @constructor
@@ -1767,7 +1813,9 @@
 					menu:    'gallery'
 				}),
 
-				new media.controller.GalleryAdd()
+				new media.controller.GalleryAdd(),
+
+				new media.controller.EditImage( { selection: options.selection } )
 			]);
 
 
@@ -1795,6 +1843,7 @@
 
 				content: {
 					'embed':          'embedContent',
+					'edit-image':     'editImageContent',
 					'edit-selection': 'editSelectionContent'
 				},
 
@@ -1893,6 +1942,17 @@
 			this.content.set( view );
 		},
 
+		editImageContent: function() {
+			var selection = this.state().get('selection'),
+				view = new media.view.EditImage( { model: selection.single(), controller: this } ).render();
+
+			this.content.set( view );
+
+			// after bringing in the frame, load the actual editor via an ajax call
+			view.loadEditor();
+
+		},
+
 		// Toolbars
 
 		/**
@@ -2064,6 +2124,7 @@
 			media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments );
 			this.on( 'menu:create:image-details', this.createMenu, this );
 			this.on( 'content:render:image-details', this.renderImageDetailsContent, this );
+			this.on( 'content:render:edit-image', this.editImageContent, this );
 			this.on( 'menu:render:image-details', this.renderMenu, this );
 			this.on( 'toolbar:render:image-details', this.renderImageDetailsToolbar, this );
 			// override the select toolbar
@@ -2087,7 +2148,8 @@
 					toolbar: 'replace',
 					priority:  80,
 					displaySettings: true
-				})
+				}),
+				new media.controller.EditImage( { image: this.image } )
 			]);
 		},
 
@@ -2127,6 +2189,23 @@
 
 		},
 
+		editImageContent: function() {
+			var attachment = this.state().get('image').attachment,
+				view;
+
+			if ( ! attachment ) {
+				return;
+			}
+
+			view = new media.view.EditImage( { model: attachment, controller: this } ).render();
+
+			this.content.set( view );
+
+			// after bringing in the frame, load the actual editor via an ajax call
+			view.loadEditor();
+
+		},
+
 		renderImageDetailsToolbar: function() {
 			this.toolbar.set( new media.view.Toolbar({
 				controller: this,
@@ -4926,8 +5005,9 @@
 			}
 		},
 
-		editAttachment: function() {
-			this.$el.addClass('needs-refresh');
+		editAttachment: function( event ) {
+			event.preventDefault();
+			this.controller.setState( 'edit-image' );
 		},
 		/**
 		 * @param {Object} event
@@ -4937,6 +5017,7 @@
 			event.preventDefault();
 			this.model.fetch();
 		}
+
 	});
 
 	/**
@@ -5210,7 +5291,9 @@
 	media.view.ImageDetails = media.view.Settings.AttachmentDisplay.extend({
 		className: 'image-details',
 		template:  media.template('image-details'),
-
+		events: {
+			'click .edit-attachment': 'editAttachment'
+		},
 		initialize: function() {
 			// used in AttachmentDisplay.prototype.updateLinkTo
 			this.options.attachment = this.model.attachment;
@@ -5250,6 +5333,44 @@
 		resetFocus: function() {
 			this.$( '.caption textarea' ).focus();
 			this.$( '.embed-image-settings' ).scrollTop( 0 );
+		},
+
+		editAttachment: function( event ) {
+			event.preventDefault();
+			this.controller.setState( 'edit-image' );
 		}
 	});
+
+
+	media.view.EditImage = media.View.extend({
+
+		className: 'image-editor',
+		template: media.template('image-editor'),
+
+		initialize: function( options ) {
+			this.editor = window.imageEdit;
+			this.controller = options.controller;
+			media.View.prototype.initialize.apply( this, arguments );
+		},
+
+		prepare: function() {
+			return this.model.toJSON();
+		},
+
+		render: function() {
+			media.View.prototype.render.apply( this, arguments );
+			return this;
+		},
+
+		loadEditor: function() {
+			this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
+		},
+
+		cancel: function() {
+				var lastState = this.controller.lastState();
+				this.controller.setState( lastState );
+		}
+
+	});
+
 }(jQuery));
Index: src/wp-includes/media-template.php
===================================================================
--- src/wp-includes/media-template.php	(revision 27233)
+++ src/wp-includes/media-template.php	(working copy)
@@ -508,6 +508,9 @@
 				<div class="thumbnail">
 					<img src="{{ data.model.url }}" draggable="false" />
 				</div>
+				<# if ( data.attachment ) { #>
+					<input type="button" class="edit-attachment button" value="<?php esc_attr_e( 'Edit Image' ); ?>" />
+				<# } #>
 
 				<div class="setting url">
 					<?php // might want to make the url editable if it isn't an attachment ?>
@@ -597,6 +600,11 @@
 			</div>
 		</div>
 	</script>
+
+	<script type="text/html" id="tmpl-image-editor">
+		<div id="media-head-{{{ data.id }}}"></div>
+		<div id="image-editor-{{{ data.id }}}"></div>
+	</script>
 	<?php
 
 	/**
Index: src/wp-includes/media.php
===================================================================
--- src/wp-includes/media.php	(revision 27233)
+++ src/wp-includes/media.php	(working copy)
@@ -1869,12 +1869,14 @@
 		'nonces'      => array(
 			'update' => false,
 			'delete' => false,
+			'edit'   => false
 		),
 		'editLink'   => false,
 	);
 
 	if ( current_user_can( 'edit_post', $attachment->ID ) ) {
 		$response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
+		$response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID );
 		$response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' );
 	}
 
@@ -2083,6 +2085,7 @@
 
 	wp_enqueue_script( 'media-editor' );
 	wp_enqueue_style( 'media-views' );
+	wp_enqueue_style( 'imgareaselect' );
 	wp_plupload_default_settings();
 
 	require_once ABSPATH . WPINC . '/media-template.php';
Index: src/wp-includes/script-loader.php
===================================================================
--- src/wp-includes/script-loader.php	(revision 27233)
+++ src/wp-includes/script-loader.php	(working copy)
@@ -389,7 +389,7 @@
 	// To enqueue media-views or media-editor, call wp_enqueue_media().
 	// Both rely on numerous settings, styles, and templates to operate correctly.
 	$scripts->add( 'media-views',  "/wp-includes/js/media-views$suffix.js",  array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable' ), false, 1 );
-	$scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 );
+	$scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views', 'image-edit' ), false, 1 );
 	$scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 );
 
 	if ( is_admin() ) {
