Index: comment.php
===================================================================
--- comment.php	(revision 9193)
+++ comment.php	(working copy)
@@ -618,6 +618,7 @@
 	clean_comment_cache($comment_id);
 
 	do_action('wp_set_comment_status', $comment_id, 'delete');
+	wp_transition_comment_status('delete', $comment->comment_approved, $comment);
 	return true;
 }
 
@@ -649,6 +650,45 @@
 }
 
 /**
+ * Call hooks for when a comment status transition occurs.
+ *
+ * Calls hooks for comment status transitions. If the new comment status is not the same
+ * as the previous comment status, then two hooks will be ran, the first is
+ * 'transition_comment_status' with new status, old status, and comment data. The
+ * next action called is 'comment_OLDSTATUS_to_NEWSTATUS' the NEWSTATUS is the
+ * $new_status parameter and the OLDSTATUS is $old_status parameter; it has the
+ * comment data.
+ *
+ * The final action will run whether or not the comment statuses are the same. The
+ * action is named 'comment_NEWSTATUS_COMMENTTYPE', NEWSTATUS is from the $new_status
+ * parameter and comment_NEWSTATUS_COMMENTTYPE is comment_type comment data.
+ *
+ * @since 2.7.0
+ *
+ * @param string $new_status New comment status.
+ * @param string $old_status Previous comment status.
+ * @param object $comment Comment data.
+ */
+function wp_transition_comment_status($new_status, $old_status, $comment) {
+	// Translate raw statuses to human readable formats for the hooks
+	$comment_statuses = array(
+		0         => 'unapproved',
+		'hold'    => 'unapproved', // wp_set_comment_status() uses "hold"
+		1         => 'approved',
+		'approve' => 'approved', // wp_set_comment_status() uses "approve"
+	);
+	if ( isset($comment_statuses[$new_status]) ) $new_status = $comment_statuses[$new_status];
+	if ( isset($comment_statuses[$old_status]) ) $old_status = $comment_statuses[$old_status];
+
+	// Call the hooks
+	if ( $new_status != $old_status ) {
+		do_action('transition_comment_status', $new_status, $old_status, $comment);
+		do_action("comment_${old_status}_to_$new_status", $comment);
+	}
+	do_action("comment_${new_status}_$comment->comment_type", $comment->ID, $comment);
+}
+
+/**
  * Get current commenter's name, email, and URL.
  *
  * Expects cookies content to already be sanitized. User of this function might
@@ -868,8 +908,11 @@
 
 	clean_comment_cache($comment_id);
 
+	$comment = get_comment($comment_id);
+
 	do_action('wp_set_comment_status', $comment_id, $comment_status);
-	$comment = get_comment($comment_id);
+	wp_transition_comment_status($comment_status, $comment->comment_approved, $comment);
+
 	wp_update_comment_count($comment->comment_post_ID);
 
 	return true;
@@ -938,6 +981,7 @@
 	clean_comment_cache($comment_ID);
 	wp_update_comment_count($comment_post_ID);
 	do_action('edit_comment', $comment_ID);
+	wp_transition_comment_status($comment_approved, $comment->comment_approved, $comment);
 	return $rval;
 }
 
