Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 21097)
+++ wp-includes/post.php	(working copy)
@@ -2859,7 +2859,7 @@
 	} elseif ( in_array( $post_type, $hierarchical_post_types ) ) {
 		// Page slugs must be unique within their own trees. Pages are in a separate
 		// namespace than posts so page slugs are allowed to overlap post slugs.
-		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d LIMIT 1";
+		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d AND post_status != 'trash' LIMIT 1";
 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID, $post_parent ) );
 
 		if ( $post_name_check || in_array( $slug, $feeds ) || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug )  || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
@@ -2873,7 +2873,7 @@
 		}
 	} else {
 		// Post slugs must be unique across all posts.
-		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
+		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_status != 'trash' LIMIT 1";
 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );
 
 		if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
Index: wp-admin/includes/post.php
===================================================================
--- wp-admin/includes/post.php	(revision 21097)
+++ wp-admin/includes/post.php	(working copy)
@@ -1114,6 +1114,22 @@
 		}
 	}
 
+	// Permalink conflict error messages.
+	if ( $new_slug && $new_slug != $post_name_abridged ) {
+		echo '<div id="message" class="error"><p>';
+		$conflicting_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_name = %s;",$new_slug)); 
+		if ( $conflicting_post->post_status == 'trash' ) {
+			_e('There was a permalink conflict with the post "' . $post->post_title . '" in the trash. <a href="edit.php?post_status=trash&amp;post_type=' . $post->post_type . '">View Trash</a>');
+		} else {
+			$conflicting_post_edit_link_url = get_edit_post_link($conflicting_post->ID);
+			$post_type_obj = get_post_type_object( $post->post_type );
+			$conflicting_post_edit_link_html = '<a class="post-edit-link" href="' . $conflicting_post_edit_link_url . '" title="' . esc_attr( $post_type_obj->labels->edit_item ) . '">' . $conflicting_post->post_title . '</a>';	
+			if ( !empty($conflicting_post) )
+				_e('There was a permalink conflict with the post ' . $conflicting_post_edit_link_html . ', a unique numerical string has been appended to the permalink.'); 
+		}
+		echo '</p></div>';
+	}
+
 	$post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
 	$display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink);
 	$view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink);
Index: wp-admin/post.php
===================================================================
--- wp-admin/post.php	(revision 21097)
+++ wp-admin/post.php	(working copy)
@@ -223,6 +223,8 @@
 	if ( ! wp_untrash_post($post_id) )
 		wp_die( __('Error in restoring from Trash.') );
 
+	$sendback = add_query_arg('ids', $post_id, $sendback);
+	
 	wp_redirect( add_query_arg('untrashed', 1, $sendback) );
 	exit();
 	break;
Index: wp-admin/edit.php
===================================================================
--- wp-admin/edit.php	(revision 21097)
+++ wp-admin/edit.php	(working copy)
@@ -97,8 +97,10 @@
 					wp_die( __('Error in restoring from Trash.') );
 
 				$untrashed++;
+				$untrashed_posts[] = $post_id;				
 			}
-			$sendback = add_query_arg('untrashed', $untrashed, $sendback);
+			$sendback = add_query_arg( 'ids', implode( '+', $untrashed_posts), $sendback );
+			$sendback = add_query_arg( 'untrashed', $untrashed, $sendback );
 			break;
 		case 'delete':
 			$deleted = 0;
@@ -251,7 +253,6 @@
 if ( isset( $_REQUEST['untrashed'] ) && $untrashed = absint( $_REQUEST['untrashed'] ) ) {
 	$messages[] = sprintf( _n( 'Item restored from the Trash.', '%s items restored from the Trash.', $untrashed ), number_format_i18n( $untrashed ) );
 }
-
 if ( $messages )
 	echo join( ' ', $messages );
 unset( $messages );
@@ -259,6 +260,21 @@
 $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'locked', 'skipped', 'updated', 'deleted', 'trashed', 'untrashed' ), $_SERVER['REQUEST_URI'] );
 ?>
 </p></div>
+<?php
+// Post permalink collision errors
+if ( isset( $_REQUEST['untrashed'] ) && $untrashed = absint( $_REQUEST['untrashed'] ) && isset($_REQUEST['ids']) && $_REQUEST['ids'] ) {
+	$posts_restored = explode( ' ', $_REQUEST['ids'] );
+	foreach ( $posts_restored as $id ) {
+		$post = get_post($id);
+		if ( $post->post_name != sanitize_title($post->post_title) ) {?>
+			<div id="message" class="error"><p>
+			<?php printf( __( 'While restoring from trash, the post %s\'s slug was set to %s because of a permalink collision.'), $post->post_title, $post->post_name );
+			?></p>
+			</div><?php
+		}
+	}
+}
+?>
 <?php } ?>
 
 <?php $wp_list_table->views(); ?>
Index: wp-admin/css/wp-admin.dev.css
===================================================================
--- wp-admin/css/wp-admin.dev.css	(revision 21097)
+++ wp-admin/css/wp-admin.dev.css	(working copy)
@@ -2932,7 +2932,6 @@
 }
 
 #edit-slug-box {
-	height: 1em;
 	margin-top: 8px;
 	padding: 0 10px;
 }
