Index: wp-includes/js/wp-lists.dev.js
===================================================================
--- wp-includes/js/wp-lists.dev.js	(revision 11972)
+++ wp-includes/js/wp-lists.dev.js	(working copy)
@@ -1,5 +1,5 @@
 (function($) {
-var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'}, wpList;
+var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'}, wpList, noticetimer;
 
 wpList = {
 	settings: {
@@ -121,6 +121,7 @@
 
 		s.element = cls[2] || s.element || null;
 		if ( cls[3] ) { s.delColor = '#' + cls[3]; }
+		else if ($(s.target).parents('span.undo').size() || $(s.target).parents('span.untrash').size()) { s.delColor = '#339900'; }
 		else { s.delColor = s.delColor || '#FF3333'; }
 
 		if ( !s || !s.element ) { return false; }
@@ -146,9 +147,38 @@
 			anim = 'slideUp';
 			if ( element.css( 'display' ).match(/table/) )
 				anim = 'fadeOut'; // Can't slideup table rows and other table elements.  Known jQuery bug
-			element
-				.animate( { backgroundColor: s.delColor }, 'fast'  )[anim]( 'fast' )
-				.queue( function() { list.wpList.recolor(); $(this).dequeue(); } );
+			element.animate( { backgroundColor: s.delColor }, 'fast'  );
+				
+			if ($(s.target).parents('span.trash').size() && s.data.untrash_nonce) {
+				$('#trashnoticerow').hide().insertAfter(element);
+				element.queue(function() {
+					$('#trashnoticerow').show();
+					$(this).hide();
+					list.wpList.recolor();
+					$(this).dequeue();
+				});
+				$('#trashnoticerow').css({backgroundColor:s.delColor}).animate({backgroundColor:'#ffffff'}, 'slow');
+				$('#trashnoticerow a:first').attr('href','comment.php?action=untrashcomment&c='+s.data.id+'&_wpnonce='+s.data.untrash_nonce);
+				$('#trashnoticerow a:first').attr('class','delete:the-comment-list:comment-'+s.data.id+'::undo=1&untrash=1 vim-t vim-destructive');
+				$('#trashnoticerow a:first').click(function() { $(this).unbind('click'); return list.wpList.del(this); });
+				if (element.is('.unapproved')) $('#trashnoticerow span:first').addClass('unapprove').removeClass('approve');
+				else $('#trashnoticerow span:first').addClass('approve').removeClass('unapprove');
+				clearTimeout(noticetimer);
+				noticetimer = setTimeout(function() {$('#trashnoticerow')[anim]('slow')}, 30000);
+			}
+			else if ($(s.target).parents('span.undo').size() && s.data.undo) {
+				$('#trashnoticerow').animate({backgroundColor:s.delColor}, 'fast');
+				$('#trashnoticerow').prev().css({backgroundColor:s.delColor})
+				$('#trashnoticerow').queue(function() {
+					var bg = $(this).prev().is('.unapproved') ? '#ffffe0' : $(this).prev().is('.alt') ? '#f9f9f9' : '#ffffff';
+					$(this).prev().show().animate({backgroundColor:bg}, 'slow');
+					$(this).hide();
+					list.wpList.recolor();
+					$(this).dequeue();
+				});
+				clearTimeout(noticetimer);
+			}
+			else element[anim]('fast').queue(function() { list.wpList.recolor(); $(this).dequeue(); });
 		} else {
 			list.wpList.recolor();
 		}
Index: wp-includes/comment.php
===================================================================
--- wp-includes/comment.php	(revision 11972)
+++ wp-includes/comment.php	(working copy)
@@ -889,8 +889,12 @@
 
 	//Either set comment_approved to the value in comment_meta or worse case to false which will mean moderation
 	$comment['comment_approved'] = get_comment_meta($comment_id, '_wp_trash_meta_status', true);
+	if ($comment['comment_approved'] == false) $comment['comment_approved'] = 0;
 
 	wp_update_comment($comment);
+	
+	delete_comment_meta($comment_id, '_wp_trash_meta_time');
+	delete_comment_meta($comment_id, '_wp_trash_meta_status');
 
 	do_action('untrashed_comment', $comment_id);
 
Index: wp-admin/edit-comments.php
===================================================================
--- wp-admin/edit-comments.php	(revision 11972)
+++ wp-admin/edit-comments.php	(working copy)
@@ -28,6 +28,9 @@
 	} elseif (($_REQUEST['action'] != -1 || $_REQUEST['action2'] != -1) && isset($_REQUEST['delete_comments'])) {
 		$comment_ids = $_REQUEST['delete_comments'];
 		$doaction = ($_REQUEST['action'] != -1) ? $_REQUEST['action'] : $_REQUEST['action2'];
+	} elseif ($_REQUEST['action'] == 'untrash' && isset($_REQUEST['ids'])) {
+		$comment_ids = explode(',', $_REQUEST['ids']);
+		$doaction = 'untrash';
 	} else wp_redirect($_SERVER['HTTP_REFERER']);
 
 	$approved = $unapproved = $spammed = $trashed = $untrashed = $deleted = 0;
@@ -66,7 +69,7 @@
 		}
 	}
 
-	$redirect_to = 'edit-comments.php?approved=' . $approved . '&unapproved=' . $unapproved . '&spam=' . $spammed . '&trashed=' . $trashed . '&untrashed=' . $untrashed . '&deleted=' . $deleted;
+	$redirect_to = 'edit-comments.php?approved=' . $approved . '&unapproved=' . $unapproved . '&spam=' . $spammed . '&trashed=' . $trashed . '&untrashed=' . $untrashed . '&deleted=' . $deleted . '&ids=' . join(',', $comment_ids);
 	if ( $post_id )
 		$redirect_to = add_query_arg( 'p', absint( $post_id ), $redirect_to );
 	if ( isset($_REQUEST['apage']) )
@@ -128,8 +131,9 @@
 			echo '<br />';
 		}
 		if ( $trashed > 0 ) {
-			printf( _n( '%s comment moved to the trash', '%s comments moved to the trash', $trashed ), $trashed );
-			echo ' <a href="' . admin_url('edit-comments.php?comment_status=trash') . '">' . __('View trash') . '</a><br />';
+			printf( _n( '%s comment moved to the trash.', '%s comments moved to the trash.', $trashed ), $trashed );
+			$ids = isset($_GET['ids']) ? $_GET['ids'] : 0;
+			echo ' <a href="' . esc_url( wp_nonce_url( "edit-comments.php?doaction=undo&action=untrash&ids=$ids", "bulk-comments" ) ) . '">' . __('Undo?') . '</a><br />';
 		}
 		if ( $untrashed > 0 ) {
 			printf( _n( '%s comment restored from the trash', '%s comments restored from the trash', $untrashed ), $untrashed );
@@ -414,4 +418,5 @@
 
 <?php
 wp_comment_reply('-1', true, 'detail');
+wp_comment_trashnotice('-1', true, 'detail');
 include('admin-footer.php'); ?>
Index: wp-admin/includes/dashboard.php
===================================================================
--- wp-admin/includes/dashboard.php	(revision 11972)
+++ wp-admin/includes/dashboard.php	(working copy)
@@ -509,6 +509,7 @@
 <?php	}
 
 		wp_comment_reply( -1, false, 'dashboard', false );
+		wp_comment_trashnotice( -1, false, 'dashboard', false );
 
 	else :
 ?>
@@ -527,10 +528,10 @@
 	$comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
 	$comment_link = '<a class="comment-link" href="' . esc_url(get_comment_link()) . '">#</a>';
 
-	$delete_url = esc_url( wp_nonce_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "delete-comment_$comment->comment_ID" ) );
 	$approve_url = esc_url( wp_nonce_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "approve-comment_$comment->comment_ID" ) );
 	$unapprove_url = esc_url( wp_nonce_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "unapprove-comment_$comment->comment_ID" ) );
 	$spam_url = esc_url( wp_nonce_url( "comment.php?action=deletecomment&dt=spam&p=$comment->comment_post_ID&c=$comment->comment_ID", "delete-comment_$comment->comment_ID" ) );
+	$trash_url = esc_url( wp_nonce_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID", "trash-comment_$comment->comment_ID" ) );
 
 	$actions = array();
 
@@ -541,7 +542,7 @@
 		$actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . __('Edit comment') . "'>". __('Edit') . '</a>';
 		$actions['reply'] = '<a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$comment->comment_post_ID.'\');return false;" class="vim-r hide-if-no-js" title="'.__('Reply to this comment').'" href="#">' . __('Reply') . '</a>';
 		$actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . __( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */  _x( 'Spam', 'verb' ) . '</a>';
-		$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID delete vim-d vim-destructive'>" . __('Move to Trash') . '</a>';
+		$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1&untrash_nonce=".wp_create_nonce("untrash-comment_$comment->comment_ID")." delete vim-t vim-destructive' title='" . __( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
 
 		$actions = apply_filters( 'comment_row_actions', $actions, $comment );
 
Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php	(revision 11972)
+++ wp-admin/includes/template.php	(working copy)
@@ -2173,7 +2173,7 @@
 							$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID delete vim-d vim-destructive'>" . __('Delete Permanently') . '</a>';
 						} else {
 							$actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . __( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>';
-							$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-t vim-destructive'>" . __('Trash') . '</a>';
+							$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1&untrash_nonce=".wp_create_nonce("untrash-comment_$comment->comment_ID")." delete vim-t vim-destructive' title='" . __( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
 						}
 
 						$actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . __('Edit comment') . "'>". __('Edit') . '</a>';
@@ -2357,6 +2357,35 @@
 /**
  * {@internal Missing Short Description}}
  *
+ * @since 2.9.0
+ *
+ * @param unknown_type $position
+ * @param unknown_type $checkbox
+ * @param unknown_type $mode
+ */
+function wp_comment_trashnotice($position = '1', $checkbox = false, $mode = 'single', $table_row = true) {
+	global $current_user;
+
+	$columns = get_column_headers('edit-comments');
+	$hidden = array_intersect( array_keys( $columns ), array_filter( get_hidden_columns('edit-comments') ) );
+	$col_count = count($columns) - count($hidden);
+
+if ( $table_row ) : ?>
+<table style="display:none;"><tbody id="com-trashnotice"><tr id="trashnoticerow" class="trash"><td colspan="<?php echo $col_count; ?>">
+<?php else : ?>
+<div id="com-trashnotice" style="display:none;"><div id="trashnoticerow" class="comment-item trash"><p>
+<?php endif; ?>
+<?php _e('Comment moved to the trash.') ?> <span class="undo untrash"><a href="/" class=""><?php _e( 'Undo?' ) ?></a></span>
+<?php if ( $table_row ) : ?>
+</td></tr></tbody></table>
+<?php else : ?>
+</p></div></div>
+<?php endif;
+}
+
+/**
+ * {@internal Missing Short Description}}
+ *
  * @since unknown
  *
  * @param unknown_type $currentcat
Index: wp-admin/js/edit-comments.dev.js
===================================================================
--- wp-admin/js/edit-comments.dev.js	(revision 11972)
+++ wp-admin/js/edit-comments.dev.js	(working copy)
@@ -68,10 +68,10 @@
 			n = a.html().replace(/[ ,.]+/g, '');
 			n = parseInt(n,10);
 			if ( isNaN(n) ) return;
-			if ( $('#' + settings.element).is('.unapproved') ) { // we deleted a formerly unapproved comment
+			if ( $(settings.target).parents( 'span.unapprove' ).size() ) { // we "deleted" an approved comment from the approved list by clicking "Unapprove"
+				n = n + 1;
+			} else if ( $('#' + settings.element).is('.unapproved') ) { // we deleted a formerly unapproved comment
 				n = n - 1;
-			} else if ( $(settings.target).parents( 'span.unapprove' ).size() ) { // we "deleted" an approved comment from the approved list by clicking "Unapprove"
-				n = n + 1;
 			}
 			if ( n < 0 ) { n = 0; }
 			a.parents('#awaiting-mod')[ 0 == n ? 'addClass' : 'removeClass' ]('count-0');
@@ -105,6 +105,8 @@
 			if ( isNaN(n) ) return;
 			if ( $(settings.target).parents( 'span.trash' ).size() ) { // we trashed a comment
 				n = n + 1;
+			} else if ( $(settings.target).parents( 'span.untrash' ).size() ) { // we undid the trashing of a comment
+				n = n - 1;
 			} else if ( $('#' + settings.element).is('.trash') ) { // we deleted or untrashed a trash comment
 				n = n - 1;
 			}
Index: wp-admin/css/dashboard.dev.css
===================================================================
--- wp-admin/css/dashboard.dev.css	(revision 11972)
+++ wp-admin/css/dashboard.dev.css	(working copy)
@@ -202,6 +202,10 @@
 	border-top: 1px solid;
 }
 
+#the-comment-list #trashnoticerow {
+	padding: 0.25em 10px 0.25em 70px;
+}
+
 #the-comment-list .pingback {
 	padding-left: 9px !important;
 }

