Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 23400)
+++ wp-includes/post.php	(working copy)
@@ -30,7 +30,7 @@
 		'rewrite' => false,
 		'query_var' => false,
 		'delete_with_user' => true,
-		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ),
+		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'advanced-revisions', 'post-formats' ),
 	) );
 
 	register_post_type( 'page', array(
@@ -47,7 +47,7 @@
 		'rewrite' => false,
 		'query_var' => false,
 		'delete_with_user' => true,
-		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ),
+		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions', 'advanced-revisions' ),
 	) );
 
 	register_post_type( 'attachment', array(
@@ -79,6 +79,7 @@
 		'labels' => array(
 			'name' => __( 'Revisions' ),
 			'singular_name' => __( 'Revision' ),
+			'edit_item' => __( 'Edit Revision' ),
 		),
 		'public' => false,
 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
@@ -5241,7 +5242,16 @@
 		return $post;
 
 	$preview = wp_get_post_autosave($post->ID);
+	$autosave_id = ( $preview ) ? $preview->ID : 0;
 
+	$preview_id = (int) $_GET['preview_id'];
+	if ( $autosave_id != $preview_id && current_user_can( 'read_post', $preview_id ) ) {
+		$revision = get_post( $preview_id );
+		if ( 'revision' == $revision->post_type && $revision->post_parent == $post->ID ) {
+			$preview = $revision;
+		}
+	}
+
 	if ( ! is_object($preview) )
 		return $post;
 
Index: wp-admin/includes/post.php
===================================================================
--- wp-admin/includes/post.php	(revision 23400)
+++ wp-admin/includes/post.php	(working copy)
@@ -160,6 +160,14 @@
 	$post_data['post_type'] = $post->post_type;
 	$post_data['post_mime_type'] = $post->post_mime_type;
 
+	$parent = null;
+	$is_advanced_revision = false;
+	if ( 'revision' == $post->post_type ) {
+		$parent = get_post( $post->post_parent );
+		if ( post_type_supports( $parent->post_type, 'advanced-revisions' ) )
+			$is_advanced_revision = true;
+	}
+
 	$ptype = get_post_type_object($post_data['post_type']);
 	if ( !current_user_can( $ptype->cap->edit_post, $post_ID ) ) {
 		if ( 'page' == $post_data['post_type'] )
@@ -243,8 +251,29 @@
 
 	update_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
 
-	wp_update_post( $post_data );
+	if ( ! empty( $_POST['save-version'] ) && post_type_supports( $post->post_type, 'advanced-revisions' ) ) {
+		unset( $post_data['post_ID'], $post_data['ID'] );
+		$post_data['post_type'] = 'revision';
+		$post_data['post_parent'] = $post_ID;
+		$post_data['post_status'] = 'draft';
+	}
 
+	if ( ! empty( $_POST['publish'] ) && $is_advanced_revision ) {
+		if ( ! current_user_can( 'edit_post', $parent->ID ) )
+			wp_die( __( 'You are not allowed to edit this post.' ) );
+
+		unset( $post_data['post_parent'] );
+		$post_data['post_type'] = $parent->post_type;
+		$post_data['post_status'] = $parent->post_status;
+		$post_data['ID'] = $parent->ID;
+		$post_data['post_ID'] = $parent->ID;
+
+		// Discard the revision
+		wp_delete_post( $post->ID, true );
+	}
+
+	$post_ID = ( ! empty( $post_data['ID'] ) ) ? wp_update_post( $post_data ) : wp_insert_post( $post_data );
+
 	// Now that we have an ID we can fix any attachment anchor hrefs
 	_fix_attachment_links( $post_ID );
 
@@ -1279,6 +1308,14 @@
 	$_POST['ID'] = $post_ID;
 	$post = get_post($post_ID);
 
+	$parent = null;
+	$is_advanced_revision = null;
+	if ( 'revision' == $post->post_type ) {
+		$parent = get_post( $post->post_parent );
+		if ( post_type_supports( $parent->post_type, 'advanced-revisions' ) )
+			$is_advanced_revision = true;
+	}
+
 	if ( 'page' == $post->post_type ) {
 		if ( !current_user_can('edit_page', $post_ID) )
 			wp_die(__('You are not allowed to edit this page.'));
@@ -1287,6 +1324,12 @@
 			wp_die(__('You are not allowed to edit this post.'));
 	}
 
+	if ( $is_advanced_revision ) {
+		$nonce = wp_create_nonce( 'post_preview_' . $post->ID );
+		$url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $post->ID, 'preview_nonce' => $nonce ), get_permalink( $parent->ID ) );
+		return $url;
+	}
+
 	if ( 'draft' == $post->post_status ) {
 		$id = edit_post();
 	} else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
Index: wp-admin/includes/meta-boxes.php
===================================================================
--- wp-admin/includes/meta-boxes.php	(revision 23400)
+++ wp-admin/includes/meta-boxes.php	(working copy)
@@ -15,6 +15,13 @@
 	$post_type = $post->post_type;
 	$post_type_object = get_post_type_object($post_type);
 	$can_publish = current_user_can($post_type_object->cap->publish_posts);
+
+	$parent = null;
+	$is_advanced_revision = false;
+	if ( 'revision' == $post->post_type && $post->post_parent ) {
+		$parent = get_post( $post->post_parent );
+		$is_advanced_revision = post_type_supports( $parent->post_type, 'advanced-revisions' );
+	}
 ?>
 <div class="submitbox" id="submitpost">
 
@@ -27,14 +34,18 @@
 
 <div id="minor-publishing-actions">
 <div id="save-action">
-<?php if ( 'publish' != $post->post_status && 'future' != $post->post_status && 'pending' != $post->post_status ) { ?>
+<?php if ( $is_advanced_revision ) { ?>
+<input type="submit" name="save" id="save-post" value="<?php esc_attr_e( 'Save Changes' ); ?>" class="button" />
+<?php } elseif ( 'publish' != $post->post_status && 'future' != $post->post_status && 'pending' != $post->post_status ) { ?>
 <input <?php if ( 'private' == $post->post_status ) { ?>style="display:none"<?php } ?> type="submit" name="save" id="save-post" value="<?php esc_attr_e('Save Draft'); ?>" class="button" />
 <?php } elseif ( 'pending' == $post->post_status && $can_publish ) { ?>
 <input type="submit" name="save" id="save-post" value="<?php esc_attr_e('Save as Pending'); ?>" class="button" />
+<?php } elseif ( 'publish' == $post->post_status && post_type_supports( $post->post_type, 'advanced-revisions' ) ) { ?>
+<input type="submit" name="save-version" id="save-post" value="<?php esc_attr_e( 'Save a Version' ); ?>" class="button" />
 <?php } ?>
 <span class="spinner"></span>
 </div>
-<?php if ( $post_type_object->public ) : ?>
+<?php if ( $post_type_object->public || $is_advanced_revision ) : ?>
 <div id="preview-action">
 <?php
 if ( 'publish' == $post->post_status ) {
@@ -43,7 +54,7 @@
 } else {
 	$preview_link = set_url_scheme( get_permalink( $post->ID ) );
 	$preview_link = esc_url( apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', $preview_link ) ) );
-	$preview_button = __( 'Preview' );
+	$preview_button = ( $is_advanced_revision ) ? __( 'Preview Changes' ) : __( 'Preview' );
 }
 ?>
 <a class="preview button" href="<?php echo $preview_link; ?>" target="wp-preview" id="post-preview"><?php echo $preview_button; ?></a>
@@ -54,6 +65,8 @@
 </div><!-- #minor-publishing-actions -->
 
 <div id="misc-publishing-actions">
+<?php if ( $is_advanced_revision ) : ?>
+<?php else: ?>
 
 <div class="misc-pub-section"><label for="post_status"><?php _e('Status:') ?></label>
 <span id="post-status-display">
@@ -181,7 +194,8 @@
 <?php endif; ?>
 
 <?php do_action('post_submitbox_misc_actions'); ?>
-</div>
+<?php endif; // $is_advanced_revision ?>
+</div><!-- #misc-publishing-actions -->
 <div class="clear"></div>
 </div>
 
@@ -194,8 +208,15 @@
 		$delete_text = __('Delete Permanently');
 	else
 		$delete_text = __('Move to Trash');
+
+	$delete_link = get_delete_post_link( $post->ID );
+	if ( $is_advanced_revision ) {
+		$delete_text = __( 'Discard Changes' );
+		$delete_link = add_query_arg( 'post', $post->ID, get_delete_post_link( $post->post_parent, '', true ) );
+		$delete_link = wp_nonce_url( $delete_link, "delete-post_{$post->ID}" );
+	}
 	?>
-<a class="submitdelete deletion" href="<?php echo get_delete_post_link($post->ID); ?>"><?php echo $delete_text; ?></a><?php
+<a class="submitdelete deletion" href="<?php echo esc_url( $delete_link ); ?>"><?php echo esc_html( $delete_text ); ?></a><?php
 } ?>
 </div>
 
@@ -208,8 +229,12 @@
 		<input name="original_publish" type="hidden" id="original_publish" value="<?php esc_attr_e('Schedule') ?>" />
 		<?php submit_button( __( 'Schedule' ), 'primary button-large', 'publish', false, array( 'accesskey' => 'p' ) ); ?>
 <?php	else : ?>
+		<?php $publish_label = ( $is_advanced_revision ) ? __( 'Publish Changes' ) : __( 'Publish' ); ?>
+		<?php if ( $is_advanced_revision ) : ?>
+		<input name="publish_revision" type="hidden" value="1" />
+		<?php endif; ?>
 		<input name="original_publish" type="hidden" id="original_publish" value="<?php esc_attr_e('Publish') ?>" />
-		<?php submit_button( __( 'Publish' ), 'primary button-large', 'publish', false, array( 'accesskey' => 'p' ) ); ?>
+		<?php submit_button( $publish_label, 'primary button-large', 'publish', false, array( 'accesskey' => 'p' ) ); ?>
 <?php	endif;
 	else : ?>
 		<input name="original_publish" type="hidden" id="original_publish" value="<?php esc_attr_e('Submit for Review') ?>" />
Index: wp-admin/post.php
===================================================================
--- wp-admin/post.php	(revision 23400)
+++ wp-admin/post.php	(working copy)
@@ -31,6 +31,20 @@
 if ( $post ) {
 	$post_type = $post->post_type;
 	$post_type_object = get_post_type_object( $post_type );
+
+	if ( post_type_supports( $post_type, 'advanced-revisions' ) ) {
+		$revisions = get_posts( array(
+			'post_parent' => $post->ID,
+			'post_type' => 'revision',
+			'post_status' => array( 'draft' ),
+		) );
+
+		if ( ! empty( $revisions ) && is_array( $revisions ) ) {
+			$revision = $revisions[0];
+			if ( current_user_can( 'edit_post', $revision->ID ) )
+				redirect_post( $revision->ID );
+		}
+	}
 }
 
 /**
@@ -39,7 +53,17 @@
  * @param int $post_id Optional. Post ID.
  */
 function redirect_post($post_id = '') {
-	if ( isset($_POST['save']) || isset($_POST['publish']) ) {
+	$post = get_post( $post_id );
+
+	$parent = null;
+	$is_advanced_revision = false;
+	if ( 'revision' == $post->post_type ) {
+		$parent = get_post( $post->post_parent );
+		if ( post_type_supports( $parent->post_type, 'advanced-revisions' ) )
+			$is_advanced_revision = true;
+	}
+
+	if ( ( isset( $_POST['save'] ) || isset( $_POST['publish'] ) ) && ! $is_advanced_revision ) {
 		$status = get_post_status( $post_id );
 
 		if ( isset( $_POST['publish'] ) ) {
@@ -57,6 +81,9 @@
 				$message = 'draft' == $status ? 10 : 1;
 		}
 
+		if ( ! empty( $_POST['publish_revision'] ) )
+			$message = 13;
+
 		$location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) );
 	} elseif ( isset($_POST['addmeta']) && $_POST['addmeta'] ) {
 		$location = add_query_arg( 'message', 2, wp_get_referer() );
@@ -68,6 +95,16 @@
 		$location = $location[0] . '#postcustom';
 	} elseif ( 'post-quickpress-save-cont' == $_POST['action'] ) {
 		$location = "post.php?action=edit&post=$post_id&message=7";
+	} elseif ( $is_advanced_revision ) {
+		$location = add_query_arg( 'post', $post->ID, get_edit_post_link( $parent->ID, 'url' ) );
+
+		if ( ! empty( $_POST['save-version'] ) )
+			$message = 11;
+		elseif ( ! empty( $_POST['save'] ) )
+			$message = 12;
+
+		if ( $message )
+			$location = add_query_arg( 'message', $message, $location );
 	} else {
 		$location = add_query_arg( 'message', 4, get_edit_post_link( $post_id, 'url' ) );
 	}
@@ -253,6 +290,12 @@
 			wp_die( __('Error in deleting.') );
 	}
 
+	if ( 'revision' == $post->post_type ) {
+		$parent = get_post( $post->post_parent );
+		$sendback = get_edit_post_link( $post->post_parent, 'url' );
+		$sendback = add_query_arg( 'message', 14, $sendback );
+	}
+
 	wp_redirect( add_query_arg('deleted', 1, $sendback) );
 	exit();
 	break;
Index: wp-admin/edit-form-advanced.php
===================================================================
--- wp-admin/edit-form-advanced.php	(revision 23400)
+++ wp-admin/edit-form-advanced.php	(working copy)
@@ -24,7 +24,15 @@
 $user_ID = isset($user_ID) ? (int) $user_ID : 0;
 $action = isset($action) ? $action : '';
 
-if ( post_type_supports($post_type, 'editor') || post_type_supports($post_type, 'thumbnail') ) {
+$parent = null;
+$is_advanced_revision = false;
+if ( 'revision' == $post->post_type ) {
+	$parent = get_post( $post->post_parent );
+	if ( post_type_supports( $parent->post_type, 'advanced-revisions' ) )
+		$is_advanced_revision = true;
+}
+
+if ( post_type_supports( $post_type, 'editor' ) || post_type_supports( $post_type, 'thumbnail' ) || ( $is_advanced_revision && post_type_supports( $parent->post_type, 'editor' ) ) ) {
 	add_thickbox();
 	wp_enqueue_media( array( 'post' => $post_ID ) );
 }
@@ -45,6 +53,10 @@
 		// translators: Publish box date format, see http://php.net/date
 		date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
 	10 => sprintf( __('Post draft updated. <a target="_blank" href="%s">Preview post</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
+	11 => __( 'A new version of this post has been created, but not published.' ),
+	12 => __( 'Your changes have been saved, but not published.' ),
+	13 => sprintf( __( 'Your changes have been saved and published. <a href="%s">View post</a>' ), esc_url( get_permalink( $post_ID ) ) ),
+	14 => __( 'Your changes have been discarded.' ),
 );
 $messages['page'] = array(
 	 0 => '', // Unused. Messages start at index 1.
@@ -58,6 +70,10 @@
 	 8 => sprintf( __('Page submitted. <a target="_blank" href="%s">Preview page</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
 	 9 => sprintf( __('Page scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview page</a>'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
 	10 => sprintf( __('Page draft updated. <a target="_blank" href="%s">Preview page</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
+	11 => __( 'A new version of this page has been created, but not published.' ),
+	12 => __( 'Your changes have been saved, but not published.' ),
+	13 => sprintf( __( 'Your changes have been saved and published. <a href="%s">View page</a>' ), esc_url( get_permalink( $post_ID ) ) ),
+	14 => __( 'Your changes have been discarded.' ),
 );
 $messages['attachment'] = array_fill( 1, 10, __( 'Media attachment updated.' ) ); // Hack, for now.
 
@@ -135,7 +151,7 @@
 if ( current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) )
 		add_meta_box('postimagediv', __('Featured Image'), 'post_thumbnail_meta_box', null, 'side', 'low');
 
-if ( post_type_supports($post_type, 'excerpt') )
+if ( post_type_supports($post_type, 'excerpt') || ( $is_advanced_revision && post_type_supports( $parent->post_type, 'excerpt' ) ) )
 	add_meta_box('postexcerpt', __('Excerpt'), 'post_excerpt_meta_box', null, 'normal', 'core');
 
 if ( post_type_supports($post_type, 'trackbacks') )
@@ -151,10 +167,10 @@
 if ( ( 'publish' == get_post_status( $post ) || 'private' == get_post_status( $post ) ) && post_type_supports($post_type, 'comments') )
 	add_meta_box('commentsdiv', __('Comments'), 'post_comment_meta_box', null, 'normal', 'core');
 
-if ( ! ( 'pending' == get_post_status( $post ) && ! current_user_can( $post_type_object->cap->publish_posts ) ) )
+if ( ! ( 'pending' == get_post_status( $post ) && ! current_user_can( $post_type_object->cap->publish_posts ) ) && ! $is_advanced_revision )
 	add_meta_box('slugdiv', __('Slug'), 'post_slug_meta_box', null, 'normal', 'core');
 
-if ( post_type_supports($post_type, 'author') ) {
+if ( post_type_supports($post_type, 'author') && ! $is_advanced_revision ) {
 	if ( is_super_admin() || current_user_can( $post_type_object->cap->edit_others_posts ) )
 		add_meta_box('authordiv', __('Author'), 'post_author_meta_box', null, 'normal', 'core');
 }
@@ -323,7 +339,7 @@
 
 <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
 <div id="post-body-content">
-<?php if ( post_type_supports($post_type, 'title') ) { ?>
+<?php if ( post_type_supports( $post_type, 'title' ) || ( $is_advanced_revision && post_type_supports( $parent->post_type, 'title' ) ) ) { ?>
 <div id="titlediv">
 <div id="titlewrap">
 	<label class="screen-reader-text" id="title-prompt-text" for="title"><?php echo apply_filters( 'enter_title_here', __( 'Enter title here' ), $post ); ?></label>
@@ -356,7 +372,7 @@
 
 do_action( 'edit_form_after_title' );
 
-if ( post_type_supports($post_type, 'editor') ) {
+if ( post_type_supports( $post_type, 'editor' ) || ( $is_advanced_revision && post_type_supports( $parent->post_type, 'editor' ) ) ) {
 ?>
 <div id="postdivrich" class="postarea">
 
