diff --git src/bbpress.php src/bbpress.php
index d56c58d..305eb1d 100644
--- src/bbpress.php
+++ src/bbpress.php
@@ -293,9 +293,10 @@ final class bbPress {
 
 		/** Misc **************************************************************/
 
-		$this->domain         = 'bbpress';      // Unique identifier for retrieving translated strings
-		$this->extend         = new stdClass(); // Plugins add data here
-		$this->errors         = new WP_Error(); // Feedback
+		$this->domain             = 'bbpress';      // Unique identifier for retrieving translated strings
+		$this->extend             = new stdClass(); // Plugins add data here
+		$this->errors             = new WP_Error(); // Feedback
+		$this->transitioned_posts = array();        // Transitioned post ids.
 
 		/** Deprecated ********************************************************/
 
diff --git src/includes/admin/forums.php src/includes/admin/forums.php
index 3c3f2c0..2229000 100644
--- src/includes/admin/forums.php
+++ src/includes/admin/forums.php
@@ -75,6 +75,12 @@ class BBP_Forums_Admin {
 		add_action( 'add_meta_boxes', array( $this, 'comments_metabox'      ) );
 		add_action( 'save_post',      array( $this, 'save_meta_boxes'       ) );
 
+		// Transitioned forum actions.
+		add_action( 'save_post', 'bbp_transitioned_forum_status_new_public',    20 );
+		add_action( 'save_post', 'bbp_transitioned_forum_status_new_moderated', 20 );
+		add_action( 'save_post', 'bbp_transitioned_forum_status_public',        20 );
+		add_action( 'save_post', 'bbp_transitioned_forum_status_moderated',     20 );
+
 		// Check if there are any bbp_toggle_forum_* requests on admin_init, also have a message displayed
 		add_action( 'load-edit.php',  array( $this, 'toggle_forum'        ) );
 		add_action( 'admin_notices',  array( $this, 'toggle_forum_notice' ) );
diff --git src/includes/admin/replies.php src/includes/admin/replies.php
index cce5647..aa35785 100644
--- src/includes/admin/replies.php
+++ src/includes/admin/replies.php
@@ -82,6 +82,12 @@ class BBP_Replies_Admin {
 		add_action( 'add_meta_boxes', array( $this, 'comments_metabox'   ) );
 		add_action( 'save_post',      array( $this, 'save_meta_boxes'    ) );
 
+		// Transitioned reply actions.
+		add_action( 'save_post', 'bbp_transitioned_reply_status_new_public',    20 );
+		add_action( 'save_post', 'bbp_transitioned_reply_status_new_moderated', 20 );
+		add_action( 'save_post', 'bbp_transitioned_reply_status_public',        20 );
+		add_action( 'save_post', 'bbp_transitioned_reply_status_moderated',     20 );
+
 		// Check if there are any bbp_toggle_reply_* requests on admin_init, also have a message displayed
 		add_action( 'load-edit.php',  array( $this, 'toggle_reply'        ) );
 		add_action( 'admin_notices',  array( $this, 'toggle_reply_notice' ) );
diff --git src/includes/admin/topics.php src/includes/admin/topics.php
index e9d2a83..b9bbfc4 100644
--- src/includes/admin/topics.php
+++ src/includes/admin/topics.php
@@ -86,6 +86,12 @@ class BBP_Topics_Admin {
 		add_action( 'add_meta_boxes', array( $this, 'comments_metabox'      ) );
 		add_action( 'save_post',      array( $this, 'save_meta_boxes'       ) );
 
+		// Transitioned topic actions.
+		add_action( 'save_post', 'bbp_transitioned_topic_status_new_public',    20 );
+		add_action( 'save_post', 'bbp_transitioned_topic_status_new_moderated', 20 );
+		add_action( 'save_post', 'bbp_transitioned_topic_status_public',        20 );
+		add_action( 'save_post', 'bbp_transitioned_topic_status_moderated',     20 );
+
 		// Check if there are any bbp_toggle_topic_* requests on admin_init, also have a message displayed
 		add_action( 'load-edit.php',  array( $this, 'toggle_topic'        ) );
 		add_action( 'admin_notices',  array( $this, 'toggle_topic_notice' ) );
diff --git src/includes/common/functions.php src/includes/common/functions.php
index ccaa650..87fd19c 100644
--- src/includes/common/functions.php
+++ src/includes/common/functions.php
@@ -1953,3 +1953,180 @@ function bbp_set_404() {
 
 	$wp_query->set_404();
 }
+
+/** Statuses ******************************************************************/
+
+/**
+ * Store the transitioned forum/topic/reply id along with it's transitioned
+ * status (new/public/moderated).
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int    $post_id The forum/topic/reply id.
+ * @param string $status  The transition status. Expects new/public/moderated.
+ *
+ * @return void
+ */
+function bbp_store_transitioned_post_id( $post_id = 0, $status = '' ) {
+
+	// Bail if we don't have all the necessary data.
+	if ( empty( $post_id ) || empty( $status ) ) {
+		return;
+	}
+
+	// Grab the globals.
+	$bbp                = bbpress();
+	$transitioned_posts = (array) $bbp->transitioned_posts;
+
+	// Store the transitioned post.
+	$transitioned_posts[ $post_id ] = $status;
+
+	// Add the new array back to the bbPress::transitioned_posts.
+	$bbp->transitioned_posts = $transitioned_posts;
+}
+
+/**
+ * Returns the transitioned post status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $post_id The forum/topic/reply id.
+ *
+ * @return string new/public/moderated. Empty on failure.
+ */
+function bbp_get_post_transitioned_status( $post_id = 0 ) {
+
+	// The bbPress global.
+	$bbp = bbpress();
+
+	// Get the transitioned post status.
+	$status = empty( $bbp->transitioned_posts[ $post_id ] )
+			  ? ''
+			  : $bbp->transitioned_posts[ $post_id ];
+
+	/**
+	 * Filters the return of `bbp_get_post_transitioned_status()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param string $status  new/public/moderated. Empty on failure.
+	 * @param int    $post_id The forum/topic/reply id.
+	 */
+	return apply_filters( 'bbp_get_post_transitioned_status', $status, $post_id );
+}
+
+/**
+ * Checks if a given post id was transitioned to new public.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $post_id The forum/topic/reply id.
+ *
+ * @return bool True if the post id was transitioned to new public.
+ */
+function bbp_is_post_transitioned_new_public( $post_id = 0 ) {
+
+	// Default to false.
+	$retval = false;
+
+	if ( 'new_public' === bbp_get_post_transitioned_status( $post_id ) ) {
+		$retval = true;
+	}
+
+	/**
+	 * Filters the return of `bbp_is_post_transitioned_new_public()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param bool $retval  True if the post was transitioned to new public.
+	 * @param int  $post_id The forum/topic/reply id.
+	 */
+	return apply_filters( 'bbp_is_post_transitioned_new_public', $retval, $post_id );
+}
+
+/**
+ * Checks if a given post id was transitioned to new moderated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $post_id The forum/topic/reply id.
+ *
+ * @return bool True if the post id was transitioned to new moderated.
+ */
+function bbp_is_post_transitioned_new_moderated( $post_id = 0 ) {
+
+	// Default to false.
+	$retval = false;
+
+	if ( 'new_moderated' === bbp_get_post_transitioned_status( $post_id ) ) {
+		$retval = true;
+	}
+
+	/**
+	 * Filters the return of `bbp_is_post_transitioned_new_moderated()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param bool $retval  True if the post was transitioned to new moderated.
+	 * @param int  $post_id The forum/topic/reply id.
+	 */
+	return apply_filters( 'bbp_is_post_transitioned_new_moderated', $retval, $post_id );
+}
+
+/**
+ * Checks if a given post id was transitioned public.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $post_id The forum/topic/reply id.
+ *
+ * @return bool True if the post id was transitioned public.
+ */
+function bbp_is_post_transitioned_public( $post_id = 0 ) {
+
+	// Default to false.
+	$retval = false;
+
+	if ( 'public' === bbp_get_post_transitioned_status( $post_id ) ) {
+		$retval = true;
+	}
+
+	/**
+	 * Filters the return of `bbp_is_post_transitioned_public()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param bool $retval  True if the post was transitioned public.
+	 * @param int  $post_id The forum/topic/reply id.
+	 */
+	return apply_filters( 'bbp_is_post_transitioned_public', $retval, $post_id );
+}
+
+/**
+ * Checks if a given post id was transitioned moderated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $post_id The forum/topic/reply id.
+ *
+ * @return bool True if the post id was transitioned moderated.
+ */
+function bbp_is_post_transitioned_moderated( $post_id = 0 ) {
+
+	// Default to false.
+	$retval = false;
+
+	if ( 'moderated' === bbp_get_post_transitioned_status( $post_id ) ) {
+		$retval = true;
+	}
+
+	/**
+	 * Filters the return of `bbp_is_post_transitioned_moderated()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param bool $retval  True if the post was transitioned moderated.
+	 * @param int  $post_id The forum/topic/reply id.
+	 */
+	return apply_filters( 'bbp_is_post_transitioned_moderated', $retval, $post_id );
+}
diff --git src/includes/core/actions.php src/includes/core/actions.php
index 1dbf139..07d216d 100644
--- src/includes/core/actions.php
+++ src/includes/core/actions.php
@@ -164,6 +164,21 @@ add_action( 'trashed_post',   'bbp_trashed_forum'   );
 add_action( 'untrashed_post', 'bbp_untrashed_forum' );
 add_action( 'deleted_post',   'bbp_deleted_forum'   );
 
+// Transition forum status.
+add_action( 'transition_post_status',      'bbp_transition_forum_status',               10, 3 );
+add_action( 'bbp_transition_forum_status', 'bbp_transition_forum_status_new_public',    10, 3 );
+add_action( 'bbp_transition_forum_status', 'bbp_transition_forum_status_new_moderated', 10, 3 );
+add_action( 'bbp_transition_forum_status', 'bbp_transition_forum_status_public',        10, 3 );
+add_action( 'bbp_transition_forum_status', 'bbp_transition_forum_status_moderated',     10, 3 );
+
+// Transitioned forum status.
+add_action( 'bbp_new_forum',       'bbp_transitioned_forum_status_new_public',    20 );
+add_action( 'bbp_new_forum',       'bbp_transitioned_forum_status_new_moderated', 20 );
+add_action( 'bbp_insert_forum',    'bbp_transitioned_forum_status_new_public',    20 );
+add_action( 'bbp_insert_forum',    'bbp_transitioned_forum_status_new_moderated', 20 );
+add_action( 'bbp_trashed_forum',   'bbp_transitioned_forum_status_moderated',     20 );
+add_action( 'bbp_untrashed_forum', 'bbp_transitioned_forum_status_public',        20 );
+
 // Auto trash/untrash/delete a forums topics
 add_action( 'bbp_delete_forum',  'bbp_delete_forum_topics',  10 );
 add_action( 'bbp_trash_forum',   'bbp_trash_forum_topics',   10 );
@@ -193,6 +208,25 @@ add_action( 'trashed_post',   'bbp_trashed_reply'   );
 add_action( 'untrashed_post', 'bbp_untrashed_reply' );
 add_action( 'deleted_post',   'bbp_deleted_reply'   );
 
+// Transition reply status.
+add_action( 'transition_post_status',      'bbp_transition_reply_status',               10, 3 );
+add_action( 'bbp_transition_reply_status', 'bbp_transition_reply_status_new_public',    10, 3 );
+add_action( 'bbp_transition_reply_status', 'bbp_transition_reply_status_new_moderated', 10, 3 );
+add_action( 'bbp_transition_reply_status', 'bbp_transition_reply_status_public',        10, 3 );
+add_action( 'bbp_transition_reply_status', 'bbp_transition_reply_status_moderated',     10, 3 );
+
+// Transitioned reply status.
+add_action( 'bbp_new_reply',        'bbp_transitioned_reply_status_new_public',    20 );
+add_action( 'bbp_new_reply',        'bbp_transitioned_reply_status_new_moderated', 20 );
+add_action( 'bbp_insert_reply',     'bbp_transitioned_reply_status_new_public',    20 );
+add_action( 'bbp_insert_reply',     'bbp_transitioned_reply_status_new_moderated', 20 );
+add_action( 'bbp_trashed_reply',    'bbp_transitioned_reply_status_moderated',     20 );
+add_action( 'bbp_untrashed_reply',  'bbp_transitioned_reply_status_public',        20 );
+add_action( 'bbp_spammed_reply',    'bbp_transitioned_reply_status_moderated',     20 );
+add_action( 'bbp_unspammed_reply',  'bbp_transitioned_reply_status_public',        20 );
+add_action( 'bbp_approved_reply',   'bbp_transitioned_reply_status_public',        20 );
+add_action( 'bbp_unapproved_reply', 'bbp_transitioned_reply_status_moderated',     20 );
+
 // New/Edit Topic
 add_action( 'bbp_new_topic',  'bbp_update_topic', 10, 5 );
 add_action( 'bbp_edit_topic', 'bbp_update_topic', 10, 5 );
@@ -215,6 +249,25 @@ add_action( 'trashed_post',   'bbp_trashed_topic'   );
 add_action( 'untrashed_post', 'bbp_untrashed_topic' );
 add_action( 'deleted_post',   'bbp_deleted_topic'   );
 
+// Transition topic status.
+add_action( 'transition_post_status',      'bbp_transition_topic_status',               10, 3 );
+add_action( 'bbp_transition_topic_status', 'bbp_transition_topic_status_new_public',    10, 3 );
+add_action( 'bbp_transition_topic_status', 'bbp_transition_topic_status_new_moderated', 10, 3 );
+add_action( 'bbp_transition_topic_status', 'bbp_transition_topic_status_public',        10, 3 );
+add_action( 'bbp_transition_topic_status', 'bbp_transition_topic_status_moderated',     10, 3 );
+
+// Transitioned topic status.
+add_action( 'bbp_new_topic',        'bbp_transitioned_topic_status_new_public',    20 );
+add_action( 'bbp_new_topic',        'bbp_transitioned_topic_status_new_moderated', 20 );
+add_action( 'bbp_insert_topic',     'bbp_transitioned_topic_status_new_public',    20 );
+add_action( 'bbp_insert_topic',     'bbp_transitioned_topic_status_new_moderated', 20 );
+add_action( 'bbp_trashed_topic',    'bbp_transitioned_topic_status_moderated',     20 );
+add_action( 'bbp_untrashed_topic',  'bbp_transitioned_topic_status_public',        20 );
+add_action( 'bbp_spammed_topic',    'bbp_transitioned_topic_status_moderated',     20 );
+add_action( 'bbp_unspammed_topic',  'bbp_transitioned_topic_status_public',        20 );
+add_action( 'bbp_approved_topic',   'bbp_transitioned_topic_status_public',        20 );
+add_action( 'bbp_unapproved_topic', 'bbp_transitioned_topic_status_moderated',     20 );
+
 // Favorites
 add_action( 'bbp_spam_topic',   'bbp_remove_topic_from_all_favorites' );
 add_action( 'bbp_trash_topic',  'bbp_remove_topic_from_all_favorites' );
@@ -253,61 +306,35 @@ add_action( 'bbp_approved_reply',   'bbp_update_reply_walker' );
 add_action( 'bbp_unapproved_reply', 'bbp_update_reply_walker' );
 
 // Update forum topic/reply counts.
-add_action( 'bbp_new_reply',        'bbp_increase_forum_reply_count'        );
-add_action( 'bbp_new_topic',        'bbp_increase_forum_topic_count'        );
-add_action( 'bbp_trashed_reply',    'bbp_decrease_forum_reply_count'        );
-add_action( 'bbp_trashed_topic',    'bbp_decrease_forum_topic_count'        );
-add_action( 'bbp_trashed_topic',    'bbp_increase_forum_topic_count_hidden' );
-add_action( 'bbp_untrashed_reply',  'bbp_increase_forum_reply_count'        );
-add_action( 'bbp_untrashed_topic',  'bbp_increase_forum_topic_count'        );
-add_action( 'bbp_untrashed_topic',  'bbp_decrease_forum_topic_count_hidden' );
-add_action( 'bbp_spammed_reply',    'bbp_decrease_forum_reply_count'        );
-add_action( 'bbp_spammed_topic',    'bbp_decrease_forum_topic_count'        );
-add_action( 'bbp_spammed_topic',    'bbp_increase_forum_topic_count_hidden' );
-add_action( 'bbp_unspammed_reply',  'bbp_increase_forum_reply_count'        );
-add_action( 'bbp_unspammed_topic',  'bbp_increase_forum_topic_count'        );
-add_action( 'bbp_unspammed_topic',  'bbp_decrease_forum_topic_count_hidden' );
-add_action( 'bbp_approved_reply',   'bbp_increase_forum_reply_count'        );
-add_action( 'bbp_approved_topic',   'bbp_increase_forum_topic_count'        );
-add_action( 'bbp_approved_topic',   'bbp_decrease_forum_topic_count_hidden' );
-add_action( 'bbp_unapproved_reply', 'bbp_decrease_forum_reply_count'        );
-add_action( 'bbp_unapproved_topic', 'bbp_decrease_forum_topic_count'        );
-add_action( 'bbp_unapproved_topic', 'bbp_increase_forum_topic_count_hidden' );
+add_action( 'bbp_transitioned_reply_status_new_public',    'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_transitioned_reply_status_public',        'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_transitioned_reply_status_moderated',     'bbp_decrease_forum_reply_count'        );
+add_action( 'bbp_transitioned_topic_status_new_public',    'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_transitioned_topic_status_new_moderated', 'bbp_increase_forum_topic_count_hidden' );
+add_action( 'bbp_transitioned_topic_status_public',        'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_transitioned_topic_status_public',        'bbp_decrease_forum_topic_count_hidden' );
+add_action( 'bbp_transitioned_topic_status_moderated',     'bbp_decrease_forum_topic_count'        );
+add_action( 'bbp_transitioned_topic_status_moderated',     'bbp_increase_forum_topic_count_hidden' );
 
 // Update forum reply counts for approved/unapproved topics.
 add_action( 'bbp_approved_topic',   'bbp_approved_unapproved_topic_update_forum_reply_count' );
 add_action( 'bbp_unapproved_topic', 'bbp_approved_unapproved_topic_update_forum_reply_count' );
 
 // Update topic reply counts.
-add_action( 'bbp_new_reply',        'bbp_increase_topic_reply_count'        );
-add_action( 'bbp_trashed_reply',    'bbp_decrease_topic_reply_count'        );
-add_action( 'bbp_trashed_reply',    'bbp_increase_topic_reply_count_hidden' );
-add_action( 'bbp_untrashed_reply',  'bbp_increase_topic_reply_count'        );
-add_action( 'bbp_untrashed_reply',  'bbp_decrease_topic_reply_count_hidden' );
-add_action( 'bbp_spammed_reply',    'bbp_decrease_topic_reply_count'        );
-add_action( 'bbp_spammed_reply',    'bbp_increase_topic_reply_count_hidden' );
-add_action( 'bbp_unspammed_reply',  'bbp_increase_topic_reply_count'        );
-add_action( 'bbp_unspammed_reply',  'bbp_decrease_topic_reply_count_hidden' );
-add_action( 'bbp_approved_reply',   'bbp_increase_topic_reply_count'        );
-add_action( 'bbp_approved_reply',   'bbp_decrease_topic_reply_count_hidden' );
-add_action( 'bbp_unapproved_reply', 'bbp_decrease_topic_reply_count'        );
-add_action( 'bbp_unapproved_reply', 'bbp_increase_topic_reply_count_hidden' );
+add_action( 'bbp_transitioned_reply_status_new_public',    'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_transitioned_reply_status_new_moderated', 'bbp_increase_topic_reply_count_hidden' );
+add_action( 'bbp_transitioned_reply_status_public',        'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_transitioned_reply_status_public',        'bbp_decrease_topic_reply_count_hidden' );
+add_action( 'bbp_transitioned_reply_status_moderated',     'bbp_decrease_topic_reply_count'        );
+add_action( 'bbp_transitioned_reply_status_moderated',     'bbp_increase_topic_reply_count_hidden' );
 
 // Users topic & reply counts.
-add_action( 'bbp_new_topic',     'bbp_increase_user_topic_count' );
-add_action( 'bbp_new_reply',     'bbp_increase_user_reply_count' );
-add_action( 'bbp_untrash_topic', 'bbp_increase_user_topic_count' );
-add_action( 'bbp_untrash_reply', 'bbp_increase_user_reply_count' );
-add_action( 'bbp_unspam_topic',  'bbp_increase_user_topic_count' );
-add_action( 'bbp_unspam_reply',  'bbp_increase_user_reply_count' );
-add_action( 'bbp_trash_topic',   'bbp_decrease_user_topic_count' );
-add_action( 'bbp_trash_reply',   'bbp_decrease_user_reply_count' );
-add_action( 'bbp_spam_topic',    'bbp_decrease_user_topic_count' );
-add_action( 'bbp_spam_reply',    'bbp_decrease_user_reply_count' );
-
-// Insert topic/reply counts.
-add_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10, 2 );
-add_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10, 3 );
+add_action( 'bbp_transitioned_reply_status_new_public', 'bbp_increase_user_reply_count' );
+add_action( 'bbp_transitioned_reply_status_public',     'bbp_increase_user_reply_count' );
+add_action( 'bbp_transitioned_reply_status_moderated',  'bbp_decrease_user_reply_count' );
+add_action( 'bbp_transitioned_topic_status_new_public', 'bbp_increase_user_topic_count' );
+add_action( 'bbp_transitioned_topic_status_public',     'bbp_increase_user_topic_count' );
+add_action( 'bbp_transitioned_topic_status_moderated',  'bbp_decrease_user_topic_count' );
 
 // Update topic voice counts.
 add_action( 'bbp_new_reply',        'bbp_update_topic_voice_count' );
diff --git src/includes/forums/functions.php src/includes/forums/functions.php
index a4f3746..ed31b48 100644
--- src/includes/forums/functions.php
+++ src/includes/forums/functions.php
@@ -1972,7 +1972,7 @@ function bbp_update_forum( $args = array() ) {
 	bbp_update_forum_subforum_count( $r['forum_id'] );
 
 	// Only update topic count if we're deleting a topic, or in the dashboard.
-	if ( in_array( current_filter(), array( 'bbp_deleted_topic', 'save_post' ), true ) ) {
+	if ( 'bbp_deleted_topic' === current_action() ) {
 		bbp_update_forum_reply_count(        $r['forum_id'] );
 		bbp_update_forum_topic_count(        $r['forum_id'] );
 		bbp_update_forum_topic_count_hidden( $r['forum_id'] );
@@ -2779,3 +2779,379 @@ function bbp_untrashed_forum( $forum_id = 0 ) {
 
 	do_action( 'bbp_untrashed_forum', $forum_id );
 }
+/** Transition Forum Statuses *************************************************/
+
+/**
+ * Called when transitioning a forum's post status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $post       The post object.
+ *
+ * @return bool
+ */
+function bbp_transition_forum_status( $new_status, $old_status, $post ) {
+
+	// Validate the forum.
+	$forum = bbp_get_forum( $post );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $forum ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a forum's post status is transitioned.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param string  $new_status The new post status.
+	 * @param string  $old_status The old post status.
+	 * @param WP_Post $forum      The forum post object.
+	 */
+	do_action( 'bbp_transition_forum_status', $new_status, $old_status, $forum );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a forum's post status to a public status from a
+ * draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $forum      The forum post object.
+ *
+ * @return bool
+ */
+function bbp_transition_forum_status_new_public( $new_status, $old_status, $forum ) {
+
+	// Validate the forum.
+	$forum = bbp_get_forum( $forum );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $forum ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	$forum_id = bbp_get_forum_id( $forum->ID );
+
+	// Store the transitioned forum id.
+	bbp_store_transitioned_post_id( $forum_id, 'new_public' );
+
+	/**
+	 * Fires when a forum's post status is transitioned to a public status from
+	 * a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transition_forum_status_new_public', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a forum's post status to a moderated status from a
+ * draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $forum      The forum post object.
+ *
+ * @return bool
+ */
+function bbp_transition_forum_status_new_moderated( $new_status, $old_status, $forum ) {
+
+	// Validate the reply.
+	$forum = bbp_get_forum( $forum );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $forum ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	$forum_id = bbp_get_forum_id( $forum->ID );
+
+	// Store the transitioned forum id.
+	bbp_store_transitioned_post_id( $forum_id, 'new_moderated' );
+
+	/**
+	 * Fires when a forum's post status is transitioned to a public status from
+	 * a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transition_forum_status_new_moderated', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a forum's post status to a public status from a
+ * moderated status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $forum      The forum post object.
+ *
+ * @return bool
+ */
+function bbp_transition_forum_status_public( $new_status, $old_status, $forum ) {
+
+	// Validate the forum.
+	$forum = bbp_get_forum( $forum );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $forum ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status moderated?
+	if ( ! in_array( $old_status, bbp_get_moderated_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	$forum_id = bbp_get_forum_id( $forum->ID );
+
+	// Store the transitioned forum id.
+	bbp_store_transitioned_post_id( $forum_id, 'public' );
+
+	/**
+	 * Fires when a forum's post status is transitioned to a public status from
+	 * a moderated status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transition_forum_status_public', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a forum's post status to a moderated status from a
+ * public status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $forum      The forum post object.
+ *
+ * @return bool
+ */
+function bbp_transition_forum_status_moderated( $new_status, $old_status, $forum ) {
+
+	// Validate the forum.
+	$forum = bbp_get_forum( $forum );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $forum ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status public?
+	if ( ! in_array( $old_status, bbp_get_public_forum_statuses(), true ) ) {
+		return false;
+	}
+
+	$forum_id = bbp_get_forum_id( $forum->ID );
+
+	// Store the transitioned forum id.
+	bbp_store_transitioned_post_id( $forum_id, 'moderated' );
+
+	/**
+	 * Fires when a forum's post status is transitioned to a moderated status
+	 * from a public status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transition_forum_status_moderated', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a forum's post status to a public status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_forum_status_new_public( $forum_id = 0 ) {
+	$forum_id = bbp_get_forum_id( $forum_id );
+
+	if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
+		return false;
+	}
+
+	// Bail if the forum wasn't transitioned to a new public status.
+	if ( ! bbp_is_post_transitioned_new_public( $forum_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a forum's post status is transitioned to a public status from
+	 * a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transitioned_forum_status_new_public', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a forum's post status to a moderated status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_forum_status_new_moderated( $forum_id = 0 ) {
+	$forum_id = bbp_get_forum_id( $forum_id );
+
+	if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
+		return false;
+	}
+
+	// Bail if the forum wasn't transitioned to a new moderated status.
+	if ( ! bbp_is_post_transitioned_new_moderated( $forum_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a forum's post status is transitioned to a moderated status
+	 * from a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transitioned_forum_status_new_moderated', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a forum's post status to a public status from a
+ * moderated status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_forum_status_public( $forum_id = 0 ) {
+	$forum_id = bbp_get_forum_id( $forum_id );
+
+	if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
+		return false;
+	}
+
+	// Bail if the forum wasn't transitioned to a public status.
+	if ( ! bbp_is_post_transitioned_public( $forum_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a forum's post status is transitioned to a public status from
+	 * a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transitioned_forum_status_public', $forum_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a forum's post status to a moderated status from a
+ * public status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_forum_status_moderated( $forum_id = 0 ) {
+	$forum_id = bbp_get_forum_id( $forum_id );
+
+	if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
+		return false;
+	}
+
+	// Bail if the forum wasn't transitioned to a moderated status.
+	if ( ! bbp_is_post_transitioned_moderated( $forum_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a forum's post status is transitioned to a moderated status
+	 * from a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_transitioned_forum_status_moderated', $forum_id );
+
+	return true;
+}
diff --git src/includes/forums/template.php src/includes/forums/template.php
index 4cce868..08cf9cc 100644
--- src/includes/forums/template.php
+++ src/includes/forums/template.php
@@ -1538,6 +1538,74 @@ function bbp_forum_status( $forum_id = 0 ) {
 	}
 
 /**
+ * Return array of draft/new forum statuses.
+ *
+ * The `new` status is applied by `wp_insert_post` when a post object has no
+ * previous status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_draft_new_forum_statuses() {
+	$statuses = array( 'auto-draft', 'draft', 'new' );
+
+	/**
+	 * Filters the return of `bbp_get_draft_new_forum_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The draft/new forum statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_draft_new_forum_statuses', $statuses );
+}
+
+/**
+ * Return array of public forum statuses.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_public_forum_statuses() {
+	$statuses = array(
+		bbp_get_public_status_id(),
+		bbp_get_closed_status_id(),
+		bbp_get_private_status_id(),
+		bbp_get_hidden_status_id(),
+	);
+
+	/**
+	 * Filters the return of `bbp_get_public_forum_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The public forum statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_public_forum_statuses', $statuses );
+}
+
+/**
+ * Return array of moderated forum statuses.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_moderated_forum_statuses() {
+	$statuses = array( bbp_get_trash_status_id() );
+
+	/**
+	 * Filters the return of `bbp_get_moderated_forum_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The moderated forum statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_moderated_forum_statuses', $statuses );
+}
+
+/**
  * Output the visibility of the forum
  *
  * @since 2.0.0 bbPress (r2997)
diff --git src/includes/replies/functions.php src/includes/replies/functions.php
index 210260a..c0b1064 100644
--- src/includes/replies/functions.php
+++ src/includes/replies/functions.php
@@ -84,6 +84,8 @@ function bbp_insert_reply( $reply_data = array(), $reply_meta = array() ) {
  * Update counts after a reply is inserted via `bbp_insert_reply`.
  *
  * @since 2.6.0 bbPress (r6036)
+ * @deprecated x.x.x bbPress (rXXXX)
+ * @todo Do we completely remove, or add a deprecation notice?
  *
  * @param int $reply_id The reply id.
  * @param int $topic_id The topic id.
@@ -1015,7 +1017,7 @@ function bbp_update_reply_walker( $reply_id, $last_active_time = '', $forum_id =
 				bbp_update_topic_last_active_time( $ancestor, $topic_last_active_time );
 
 				// Only update reply count if we're deleting a reply, or in the dashboard.
-				if ( in_array( current_filter(), array( 'bbp_deleted_reply', 'save_post' ), true ) ) {
+				if ( 'bbp_deleted_reply' === current_action() ) {
 					bbp_update_topic_reply_count(        $ancestor );
 					bbp_update_topic_reply_count_hidden( $ancestor );
 					bbp_update_topic_voice_count(        $ancestor );
@@ -1044,7 +1046,7 @@ function bbp_update_reply_walker( $reply_id, $last_active_time = '', $forum_id =
 
 				// Counts
 				// Only update reply count if we're deleting a reply, or in the dashboard.
-				if ( in_array( current_filter(), array( 'bbp_deleted_reply', 'save_post' ), true ) ) {
+				if ( 'bbp_deleted_reply' === current_action() ) {
 					bbp_update_forum_reply_count( $ancestor );
 				}
 			}
@@ -2104,6 +2106,383 @@ function bbp_untrashed_reply( $reply_id = 0 ) {
 	do_action( 'bbp_untrashed_reply', $reply_id );
 }
 
+/** Transition Reply Statuses *************************************************/
+
+/**
+ * Called when transitioning a reply's post status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $post       The post object.
+ *
+ * @return bool
+ */
+function bbp_transition_reply_status( $new_status, $old_status, $post ) {
+
+	// Validate the reply.
+	$reply = bbp_get_reply( $post );
+
+	// Bail if the post object isn't a forum.
+	if ( empty( $reply ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a reply's post status is transitioned.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param string  $new_status The new post status.
+	 * @param string  $old_status The old post status.
+	 * @param WP_Post $reply      The reply post object.
+	 */
+	do_action( 'bbp_transition_reply_status', $new_status, $old_status, $reply );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a reply's post status to a public status from a
+ * draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $reply      The reply post object.
+ *
+ * @return bool
+ */
+function bbp_transition_reply_status_new_public( $new_status, $old_status, $reply ) {
+
+	// Validate the reply.
+	$reply = bbp_get_reply( $reply );
+
+	// Bail if the post object isn't a reply.
+	if ( empty( $reply ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$reply_id = bbp_get_reply_id( $reply->ID );
+
+	// Store the transitioned reply id.
+	bbp_store_transitioned_post_id( $reply_id, 'new_public' );
+
+	/**
+	 * Fires when a reply's post status is transitioned to a public status from
+	 * a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transition_reply_status_new_public', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a reply's post status to a moderated status from a
+ * draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $reply      The reply post object.
+ *
+ * @return bool
+ */
+function bbp_transition_reply_status_new_moderated( $new_status, $old_status, $reply ) {
+
+	// Validate the reply.
+	$reply = bbp_get_reply( $reply );
+
+	// Bail if the post object isn't a reply.
+	if ( empty( $reply ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$reply_id = bbp_get_reply_id( $reply->ID );
+
+	// Store the transitioned reply id.
+	bbp_store_transitioned_post_id( $reply_id, 'new_moderated' );
+
+	/**
+	 * Fires when a reply's post status is transitioned to a public status from
+	 * a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transition_reply_status_new_moderated', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a reply's post status to a public status from a
+ * moderated status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $reply      The reply post object.
+ *
+ * @return bool
+ */
+function bbp_transition_reply_status_public( $new_status, $old_status, $reply ) {
+
+	// Validate the reply.
+	$reply = bbp_get_reply( $reply );
+
+	// Bail if the post object isn't a reply.
+	if ( empty( $reply ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status moderated?
+	if ( ! in_array( $old_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$reply_id = bbp_get_reply_id( $reply->ID );
+
+	// Store the transitioned reply id.
+	bbp_store_transitioned_post_id( $reply_id, 'public' );
+
+	/**
+	 * Fires when a reply's post status is transitioned to a public status from
+	 * a moderated status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transition_reply_status_public', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a reply's post status to a moderated status from a
+ * public status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $reply      The reply post object.
+ *
+ * @return bool
+ */
+function bbp_transition_reply_status_moderated( $new_status, $old_status, $reply ) {
+
+	// Validate the reply.
+	$reply = bbp_get_reply( $reply );
+
+	// Bail if the post object isn't a reply.
+	if ( empty( $reply ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status public?
+	if ( ! in_array( $old_status, bbp_get_public_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$reply_id = bbp_get_reply_id( $reply->ID );
+
+	// Store the transitioned reply id.
+	bbp_store_transitioned_post_id( $reply_id, 'moderated' );
+
+	/**
+	 * Fires when a reply's post status is transitioned to a moderated status
+	 * from a public status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transition_reply_status_moderated', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a reply's post status to a public status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_reply_status_new_public( $reply_id = 0 ) {
+	$reply_id = bbp_get_reply_id( $reply_id );
+
+	if ( empty( $reply_id ) || ! bbp_is_reply( $reply_id ) ) {
+		return false;
+	}
+
+	// Bail if the reply wasn't transitioned to a new public status.
+	if ( ! bbp_is_post_transitioned_new_public( $reply_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a reply's post status is transitioned to a public status from
+	 * a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transitioned_reply_status_new_public', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a reply's post status to a moderated status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_reply_status_new_moderated( $reply_id = 0 ) {
+	$reply_id = bbp_get_reply_id( $reply_id );
+
+	if ( empty( $reply_id ) || ! bbp_is_reply( $reply_id ) ) {
+		return false;
+	}
+
+	// Bail if the reply wasn't transitioned to a new moderated status.
+	if ( ! bbp_is_post_transitioned_new_moderated( $reply_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a reply's post status is transitioned to a moderated status
+	 * from a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transitioned_reply_status_new_moderated', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a reply's post status to a public status from a
+ * moderated status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_reply_status_public( $reply_id = 0 ) {
+	$reply_id = bbp_get_reply_id( $reply_id );
+
+	if ( empty( $reply_id ) || ! bbp_is_reply( $reply_id ) ) {
+		return false;
+	}
+
+	// Bail if the reply wasn't transitioned to a public status.
+	if ( ! bbp_is_post_transitioned_public( $reply_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a reply's post status is transitioned to a public status from
+	 * a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transitioned_reply_status_public', $reply_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a reply's post status to a moderated status from a
+ * public status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_reply_status_moderated( $reply_id = 0 ) {
+	$reply_id = bbp_get_reply_id( $reply_id );
+
+	if ( empty( $reply_id ) || ! bbp_is_reply( $reply_id ) ) {
+		return false;
+	}
+
+	// Bail if the reply wasn't transitioned to a moderated status.
+	if ( ! bbp_is_post_transitioned_moderated( $reply_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a reply's post status is transitioned to a moderated status
+	 * from a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 */
+	do_action( 'bbp_transitioned_reply_status_moderated', $reply_id );
+
+	return true;
+}
+
 /** Settings ******************************************************************/
 
 /**
diff --git src/includes/replies/template.php src/includes/replies/template.php
index 92ff8bf..bac3894 100644
--- src/includes/replies/template.php
+++ src/includes/replies/template.php
@@ -917,6 +917,73 @@ function bbp_reply_status( $reply_id = 0 ) {
 	}
 
 /**
+ * Return array of draft/new reply statuses.
+ *
+ * The `new` status is applied by `wp_insert_post` when a post object has no
+ * previous status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_draft_new_reply_statuses() {
+	$statuses = array( 'auto-draft', 'draft', 'new' );
+
+	/**
+	 * Filters the return of `bbp_get_draft_new_reply_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The draft/new reply statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_draft_new_reply_statuses', $statuses );
+}
+
+/**
+ * Return array of public reply statuses.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_public_reply_statuses() {
+	$statuses = array( bbp_get_public_status_id() );
+
+	/**
+	 * Filters the return of `bbp_get_public_reply_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The public reply statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_public_reply_statuses', $statuses );
+}
+
+/**
+ * Return array of moderated reply statuses.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_moderated_reply_statuses() {
+	$statuses = array(
+		bbp_get_pending_status_id(),
+		bbp_get_spam_status_id(),
+		bbp_get_trash_status_id(),
+	);
+
+	/**
+	 * Filters the return of `bbp_get_moderated_reply_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The moderated reply statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_moderated_reply_statuses', $statuses );
+}
+
+/**
  * Is the reply not spam or deleted?
  *
  * @since 2.0.0 bbPress (r3496)
diff --git src/includes/topics/functions.php src/includes/topics/functions.php
index 328581d..52527bb 100644
--- src/includes/topics/functions.php
+++ src/includes/topics/functions.php
@@ -2631,6 +2631,8 @@ function bbp_decrease_topic_reply_count_hidden( $topic_id = 0 ) {
  * Update counts after a topic is inserted via `bbp_insert_topic`.
  *
  * @since 2.6.0 bbPress (r6036)
+ * @deprecated x.x.x bbPress (rXXXX)
+ * @todo Do we completely remove, or add a deprecation notice?
  *
  * @param int $topic_id The topic id.
  * @param int $forum_id The forum id.
@@ -3916,6 +3918,383 @@ function bbp_untrashed_topic( $topic_id = 0 ) {
 	do_action( 'bbp_untrashed_topic', $topic_id );
 }
 
+/** Transition Topic Statuses *************************************************/
+
+/**
+ * Called when transitioning a topic's post status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $post       The post object.
+ *
+ * @return bool
+ */
+function bbp_transition_topic_status( $new_status, $old_status, $post ) {
+
+	// Validate the topic.
+	$topic = bbp_get_topic( $post );
+
+	// Bail if the post object isn't a topic.
+	if ( empty( $topic ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a topic's post status is transitioned.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param string  $new_status The new post status.
+	 * @param string  $old_status The old post status.
+	 * @param WP_Post $topic      The topic post object.
+	 */
+	do_action( 'bbp_transition_topic_status', $new_status, $old_status, $topic );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a topic's post status to a public status from a
+ * draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $topic      The topic post object.
+ *
+ * @return bool
+ */
+function bbp_transition_topic_status_new_public( $new_status, $old_status, $topic ) {
+
+	// Validate the topic.
+	$topic = bbp_get_topic( $topic );
+
+	// Bail if the post object isn't a topic.
+	if ( empty( $topic ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_topic_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_topic_statuses(), true ) ) {
+		return false;
+	}
+
+	$topic_id = bbp_get_topic_id( $topic->ID );
+
+	// Store the transitioned topic id.
+	bbp_store_transitioned_post_id( $topic_id, 'new_public' );
+
+	/**
+	 * Fires when a topic's post status is transitioned to a public status from
+	 * a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transition_topic_status_new_public', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a topic's post status to a moderated status
+ * from a draft/new status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $topic      The topic post object.
+ *
+ * @return bool
+ */
+function bbp_transition_topic_status_new_moderated( $new_status, $old_status, $topic ) {
+
+	// Validate the topic.
+	$topic = bbp_get_topic( $topic );
+
+	// Bail if the post object isn't a topic.
+	if ( empty( $topic ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status draft or new?
+	if ( ! in_array( $old_status, bbp_get_draft_new_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$topic_id = bbp_get_topic_id( $topic->ID );
+
+	// Store the transitioned topic id.
+	bbp_store_transitioned_post_id( $topic_id, 'new_moderated' );
+
+	/**
+	 * Fires when a topic's post status is transitioned to a moderated status
+	 * from a draft/new status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transition_topic_status_new_moderated', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a topic's post status to a public status from a
+ * moderated status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $topic      The topic post object.
+ *
+ * @return bool
+ */
+function bbp_transition_topic_status_public( $new_status, $old_status, $topic ) {
+
+	// Validate the topic.
+	$topic = bbp_get_topic( $topic );
+
+	// Bail if the post object isn't a topic.
+	if ( empty( $topic ) ) {
+		return false;
+	}
+
+	// Is the new status public?
+	if ( ! in_array( $new_status, bbp_get_public_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status moderated?
+	if ( ! in_array( $old_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$topic_id = bbp_get_topic_id( $topic->ID );
+
+	// Store the transitioned topic id.
+	bbp_store_transitioned_post_id( $topic_id, 'public' );
+
+	/**
+	 * Fires when a topic's post status is transitioned to a public status from
+	 * a moderated status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transition_topic_status_public', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called when transitioning a topic's post status to a moderated status from a
+ * public status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param string  $new_status The new post status.
+ * @param string  $old_status The old post status.
+ * @param WP_Post $topic      The topic post object.
+ *
+ * @return bool
+ */
+function bbp_transition_topic_status_moderated( $new_status, $old_status, $topic ) {
+
+	// Validate the topic.
+	$topic = bbp_get_topic( $topic );
+
+	// Bail if the post object isn't a topic.
+	if ( empty( $topic ) ) {
+		return false;
+	}
+
+	// Is the new status moderated?
+	if ( ! in_array( $new_status, bbp_get_moderated_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	// Is the old status public?
+	if ( ! in_array( $old_status, bbp_get_public_reply_statuses(), true ) ) {
+		return false;
+	}
+
+	$topic_id = bbp_get_topic_id( $topic->ID );
+
+	// Store the transitioned topic id.
+	bbp_store_transitioned_post_id( $topic_id, 'moderated' );
+
+	/**
+	 * Fires when a topic's post status is transitioned to a moderated status
+	 * from a public status.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transition_topic_status_moderated', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a topic's post status to a public status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_topic_status_new_public( $topic_id = 0 ) {
+	$topic_id = bbp_get_topic_id( $topic_id );
+
+	if ( empty( $topic_id ) || ! bbp_is_topic( $topic_id ) ) {
+		return false;
+	}
+
+	// Bail if the topic wasn't transitioned to a new public status.
+	if ( ! bbp_is_post_transitioned_new_public( $topic_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a topic's post status is transitioned to a public status from
+	 * a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transitioned_topic_status_new_public', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a topic's post status to a moderated status from a
+ * draft/new status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_topic_status_new_moderated( $topic_id = 0 ) {
+	$topic_id = bbp_get_topic_id( $topic_id );
+
+	if ( empty( $topic_id ) || ! bbp_is_topic( $topic_id ) ) {
+		return false;
+	}
+
+	// Bail if the topic wasn't transitioned to a new moderated status.
+	if ( ! bbp_is_post_transitioned_new_moderated( $topic_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a topic's post status is transitioned to a moderated status
+	 * from a draft/new status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transitioned_topic_status_new_moderated', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a topic's post status to a public status from a
+ * moderated status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_topic_status_public( $topic_id = 0 ) {
+	$topic_id = bbp_get_topic_id( $topic_id );
+
+	if ( empty( $topic_id ) || ! bbp_is_topic( $topic_id ) ) {
+		return false;
+	}
+
+	// Bail if the topic wasn't transitioned to a public status.
+	if ( ! bbp_is_post_transitioned_public( $topic_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a topic's post status is transitioned to a public status from
+	 * a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transitioned_topic_status_public', $topic_id );
+
+	return true;
+}
+
+/**
+ * Called after transitioning a topic's post status to a moderated status from a
+ * public status and it's post meta has been updated.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @return bool
+ */
+function bbp_transitioned_topic_status_moderated( $topic_id = 0 ) {
+	$topic_id = bbp_get_topic_id( $topic_id );
+
+	if ( empty( $topic_id ) || ! bbp_is_topic( $topic_id ) ) {
+		return false;
+	}
+
+	// Bail if the topic wasn't transitioned to a moderated status.
+	if ( ! bbp_is_post_transitioned_moderated( $topic_id ) ) {
+		return false;
+	}
+
+	/**
+	 * Fires when a topic's post status is transitioned to a moderated status
+	 * from a public status and it's post meta has been updated.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 */
+	do_action( 'bbp_transitioned_topic_status_moderated', $topic_id );
+
+	return true;
+}
+
 /** Settings ******************************************************************/
 
 /**
diff --git src/includes/topics/template.php src/includes/topics/template.php
index 57b122c..ca7bbaf 100644
--- src/includes/topics/template.php
+++ src/includes/topics/template.php
@@ -1167,6 +1167,29 @@ function bbp_topic_status( $topic_id = 0 ) {
 	}
 
 /**
+ * Return array of draft/new topic statuses.
+ *
+ * The `new` status is applied by `wp_insert_post` when a post object has no
+ * previous status.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_draft_new_topic_statuses() {
+	$statuses = array( 'auto-draft', 'draft', 'new' );
+
+	/**
+	 * Filters the return of `bbp_get_draft_new_topic_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The draft/new topic statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_draft_new_topic_statuses', $statuses );
+}
+
+/**
  * Return array of public topic statuses.
  *
  * @since 2.6.0 bbPress (r6383)
@@ -1179,10 +1202,41 @@ function bbp_topic_status( $topic_id = 0 ) {
 function bbp_get_public_topic_statuses() {
 	$statuses = array( bbp_get_public_status_id(), bbp_get_closed_status_id() );
 
+	/**
+	 * Filters the return of `bbp_get_public_topic_statuses()`.
+	 *
+	 * @since 2.6.0 bbPress (r6383)
+	 *
+	 * @param array $statuses The public topic statuses.
+	 */
 	return (array) apply_filters( 'bbp_get_public_topic_statuses', $statuses );
 }
 
 /**
+ * Return array of moderated topic statuses.
+ *
+ * @since x.x.x bbPress (rXXXX)
+ *
+ * @return array
+ */
+function bbp_get_moderated_topic_statuses() {
+	$statuses = array(
+		bbp_get_pending_status_id(),
+		bbp_get_spam_status_id(),
+		bbp_get_trash_status_id(),
+	);
+
+	/**
+	 * Filters the return of `bbp_get_moderated_topic_statuses()`.
+	 *
+	 * @since x.x.x bbPress (rXXXX)
+	 *
+	 * @param array $statuses The moderated topic statuses.
+	 */
+	return (array) apply_filters( 'bbp_get_moderated_topic_statuses', $statuses );
+}
+
+/**
  * Is the topic closed to new replies?
  *
  * @since 2.0.0 bbPress (r2746)
diff --git tests/phpunit/testcases/common/functions.php tests/phpunit/testcases/common/functions.php
index 02d6ddd..17d5549 100644
--- tests/phpunit/testcases/common/functions.php
+++ tests/phpunit/testcases/common/functions.php
@@ -1221,4 +1221,95 @@ class BBP_Tests_Common_Functions extends BBP_UnitTestCase {
 			'This test has not been implemented yet.'
 		);
 	}
+
+	/**
+	 * @covers ::bbp_store_transitioned_post_id
+	 */
+	public function test_bbp_store_transitioned_post_id() {
+		$bbp = bbpress();
+
+		// Reset transitioned posts.
+		$bbp->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'new' );
+		$this->assertArrayHasKey( 1, $bbp->transitioned_posts );
+
+		bbp_store_transitioned_post_id( 2, 'moderated' );
+		$this->assertArrayHasKey( 1, $bbp->transitioned_posts );
+		$this->assertArrayHasKey( 2, $bbp->transitioned_posts );
+	}
+
+	/**
+	 * @covers ::bbp_get_post_transitioned_status
+	 */
+	public function test_bbp_get_post_transitioned_status() {
+
+		// Reset transitioned posts.
+		bbpress()->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'new_public' );
+
+		$status = bbp_get_post_transitioned_status( 1 );
+		$this->assertEquals( 'new_public', $status );
+	}
+
+	/**
+	 * @covers ::bbp_is_post_transitioned_new_public
+	 */
+	public function test_bbp_is_post_transitioned_new_public() {
+
+		// Reset transitioned posts.
+		bbpress()->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'new_public' );
+		$this->assertTrue( bbp_is_post_transitioned_new_public( 1 ) );
+
+		bbp_store_transitioned_post_id( 2, 'moderated' );
+		$this->assertFalse( bbp_is_post_transitioned_new_public( 2 ) );
+	}
+
+	/**
+	 * @covers ::bbp_is_post_transitioned_new_moderated
+	 */
+	public function test_bbp_is_post_transitioned_new_moderated() {
+
+		// Reset transitioned posts.
+		bbpress()->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'new_moderated' );
+		$this->assertTrue( bbp_is_post_transitioned_new_moderated( 1 ) );
+
+		bbp_store_transitioned_post_id( 2, 'moderated' );
+		$this->assertFalse( bbp_is_post_transitioned_new_moderated( 2 ) );
+	}
+
+	/**
+	 * @covers ::bbp_is_post_transitioned_public
+	 */
+	public function test_bbp_is_post_transitioned_public() {
+
+		// Reset transitioned posts.
+		bbpress()->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'public' );
+		$this->assertTrue( bbp_is_post_transitioned_public( 1 ) );
+
+		bbp_store_transitioned_post_id( 2, 'moderated' );
+		$this->assertFalse( bbp_is_post_transitioned_public( 2 ) );
+	}
+
+	/**
+	 * @covers ::bbp_is_post_transitioned_moderated
+	 */
+	public function test_bbp_is_post_transitioned_moderated() {
+
+		// Reset transitioned posts.
+		bbpress()->transitioned_posts = array();
+
+		bbp_store_transitioned_post_id( 1, 'moderated' );
+		$this->assertTrue( bbp_is_post_transitioned_moderated( 1 ) );
+
+		bbp_store_transitioned_post_id( 2, 'new' );
+		$this->assertFalse( bbp_is_post_transitioned_moderated( 2 ) );
+	}
 }
diff --git tests/phpunit/testcases/forums/functions/counts.php tests/phpunit/testcases/forums/functions/counts.php
index eaf91d2..8cb73c0 100644
--- tests/phpunit/testcases/forums/functions/counts.php
+++ tests/phpunit/testcases/forums/functions/counts.php
@@ -13,7 +13,9 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 	 * Generic function to test the forum counts with a new topic
 	 */
 	public function test_bbp_forum_new_topic_counts() {
-		remove_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10 );
+
+		// Remove the transitioned new action so we can simulate a new topic.
+		remove_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new' );
 
 		$f = $this->factory->forum->create();
 		$t1 = $this->factory->topic->create( array(
@@ -25,11 +27,8 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		) );
 		$u = $this->factory->user->create();
 
-		// Don't attempt to send an email. This is for speed and PHP errors.
-		remove_action( 'bbp_new_topic', 'bbp_notify_forum_subscribers', 11, 4 );
-
-		// Simulate the 'bbp_new_topic' action.
-		do_action( 'bbp_new_topic', $t1, $f, false, bbp_get_current_user_id(), $t1 );
+		// Simulate the 'bbp_transitioned_topic_status_new' action.
+		do_action( 'bbp_transitioned_topic_status_new', $t1 );
 
 		$count = bbp_get_forum_topic_count( $f, true, true );
 		$this->assertSame( 1, $count );
@@ -45,8 +44,8 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 			),
 		) );
 
-		// Simulate the 'bbp_new_topic' action.
-		do_action( 'bbp_new_topic', $t2, $f, false, $u , $t2 );
+		// Simulate the 'bbp_transitioned_topic_status_new' action.
+		do_action( 'bbp_transitioned_topic_status_new', $t2 );
 
 		$count = bbp_get_forum_topic_count( $f, true, true );
 		$this->assertSame( 2, $count );
@@ -54,9 +53,8 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		$count = bbp_get_forum_topic_count_hidden( $f, true, true );
 		$this->assertSame( 0, $count );
 
-		// Re-add removed actions.
-		add_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10, 2 );
-		add_action( 'bbp_new_topic',    'bbp_notify_forum_subscribers',   11, 4 );
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new' );
 	}
 
 	/**
diff --git tests/phpunit/testcases/forums/functions/status.php tests/phpunit/testcases/forums/functions/status.php
index c9ffe1b..4987a3a 100644
--- tests/phpunit/testcases/forums/functions/status.php
+++ tests/phpunit/testcases/forums/functions/status.php
@@ -107,4 +107,147 @@ class BBP_Tests_Forums_Functions_Status extends BBP_UnitTestCase {
 			'This test has not been implemented yet.'
 		);
 	}
+
+	/**
+	 * @covers ::bbp_transition_forum_status
+	 */
+	public function test_bbp_transition_forum_status() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transition_forum_status(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_forum( $f )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transition_forum_status_new_public
+	 */
+	public function test_bbp_transition_forum_status_new_public() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transition_forum_status_new_public(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_forum( $f )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_public', bbp_get_post_transitioned_status( $f ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_forum_status_new_moderated
+	 */
+	public function test_bbp_transition_forum_status_new_moderated() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transition_forum_status_new_moderated(
+			bbp_get_trash_status_id(),
+			'new',
+			bbp_get_forum( $f )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_moderated', bbp_get_post_transitioned_status( $f ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_forum_status_public
+	 */
+	public function test_bbp_transition_forum_status_public() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transition_forum_status_public(
+			bbp_get_public_status_id(),
+			bbp_get_trash_status_id(),
+			bbp_get_forum( $f )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'public', bbp_get_post_transitioned_status( $f ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_forum_status_moderated
+	 */
+	public function test_bbp_transition_forum_status_moderated() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transition_forum_status_moderated(
+			bbp_get_trash_status_id(),
+			bbp_get_public_status_id(),
+			bbp_get_forum( $f )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'moderated', bbp_get_post_transitioned_status( $f ) );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_forum_status_new_public
+	 */
+	public function test_bbp_transitioned_forum_status_new_public() {
+		$f = $this->factory->forum->create();
+
+		$result = bbp_transitioned_forum_status_new_public( $f );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_forum_status_new_moderated
+	 */
+	public function test_bbp_transitioned_forum_status_new_moderated() {
+		$f = $this->factory->forum->create( array(
+			'post_status' => bbp_get_trash_status_id(),
+		) );
+
+		$result = bbp_transitioned_forum_status_new_moderated( $f );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_forum_status_public
+	 */
+	public function test_bbp_transitioned_forum_status_public() {
+		$f = $this->factory->forum->create();
+
+		wp_trash_post( $f );
+		wp_untrash_post( $f );
+
+		$result = bbp_transitioned_forum_status_public( $f );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_forum_status_moderated
+	 */
+	public function test_bbp_transitioned_forum_status_moderated() {
+		$f = $this->factory->forum->create();
+
+		wp_trash_post( $f );
+
+		$result = bbp_transitioned_forum_status_moderated( $f );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
 }
diff --git tests/phpunit/testcases/forums/template/status.php tests/phpunit/testcases/forums/template/status.php
index 26a9347..3e92623 100644
--- tests/phpunit/testcases/forums/template/status.php
+++ tests/phpunit/testcases/forums/template/status.php
@@ -24,6 +24,41 @@ class BBP_Tests_Forums_Template_Status extends BBP_UnitTestCase {
 	}
 
 	/**
+	 * @covers ::bbp_get_draft_new_forum_statuses
+	 */
+	public function test_bbp_get_draft_new_forum_statuses() {
+
+		$expected = array( 'auto-draft', 'draft', 'new' );
+
+		$this->assertEquals( $expected, bbp_get_draft_new_forum_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_public_forum_statuses
+	 */
+	public function test_bbp_get_public_forum_statuses() {
+
+		$expected = array(
+			bbp_get_public_status_id(),
+			bbp_get_closed_status_id(),
+			bbp_get_private_status_id(),
+			bbp_get_hidden_status_id(),
+		);
+
+		$this->assertEquals( $expected, bbp_get_public_forum_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_moderated_forum_statuses
+	 */
+	public function test_bbp_get_moderated_forum_statuses() {
+
+		$expected = array( bbp_get_trash_status_id() );
+
+		$this->assertEquals( $expected, bbp_get_moderated_forum_statuses() );
+	}
+
+	/**
 	 * @covers ::bbp_forum_type
 	 * @covers ::bbp_get_forum_type
 	 */
diff --git tests/phpunit/testcases/replies/functions/status.php tests/phpunit/testcases/replies/functions/status.php
index 7b13b90..d2e42eb 100644
--- tests/phpunit/testcases/replies/functions/status.php
+++ tests/phpunit/testcases/replies/functions/status.php
@@ -213,4 +213,263 @@ class BBP_Tests_Replies_Functions_Status extends BBP_UnitTestCase {
 		$topic_reply_count = bbp_get_topic_reply_count( $t );
 		$this->assertSame( '1', $topic_reply_count );
 	}
+
+	/**
+	 * @covers ::bbp_transition_reply_status
+	 */
+	public function test_bbp_transition_reply_status() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transition_reply_status(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_reply( $r )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transition_reply_status_new_public
+	 */
+	public function test_bbp_transition_reply_status_new_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transition_reply_status_new_public(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_reply( $r )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_public', bbp_get_post_transitioned_status( $r ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_reply_status_new_moderated
+	 */
+	public function test_bbp_transition_reply_status_new_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transition_reply_status_new_moderated(
+			bbp_get_pending_status_id(),
+			'new',
+			bbp_get_reply( $r )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_moderated', bbp_get_post_transitioned_status( $r ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_reply_status_public
+	 */
+	public function test_bbp_transition_reply_status_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transition_reply_status_public(
+			bbp_get_public_status_id(),
+			bbp_get_pending_status_id(),
+			bbp_get_reply( $r )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'public', bbp_get_post_transitioned_status( $r ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_reply_status_moderated
+	 */
+	public function test_bbp_transition_reply_status_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transition_reply_status_moderated(
+			bbp_get_pending_status_id(),
+			bbp_get_public_status_id(),
+			bbp_get_reply( $r )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'moderated', bbp_get_post_transitioned_status( $r ) );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_reply_status_new_public
+	 */
+	public function test_bbp_transitioned_reply_status_new_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transitioned_reply_status_new_public( $r );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_reply_status_new_moderated
+	 */
+	public function test_bbp_transitioned_reply_status_new_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'post_status' => bbp_get_pending_status_id(),
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		$result = bbp_transitioned_reply_status_new_moderated( $r );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_reply_status_public
+	 */
+	public function test_bbp_transitioned_reply_status_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'post_status' => bbp_get_pending_status_id(),
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		bbp_approve_reply( $r );
+
+		$result = bbp_transitioned_reply_status_public( $r );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_reply_status_moderated
+	 */
+	public function test_bbp_transitioned_reply_status_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+		$r = $this->factory->reply->create( array(
+			'post_parent' => $t,
+			'reply_meta'  => array(
+				'forum_id' => $f,
+				'topic_id' => $t,
+			),
+		) );
+
+		bbp_unapprove_reply( $r );
+
+		$result = bbp_transitioned_reply_status_moderated( $r );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
 }
diff --git tests/phpunit/testcases/replies/template/status.php tests/phpunit/testcases/replies/template/status.php
index 588e59d..203042e 100644
--- tests/phpunit/testcases/replies/template/status.php
+++ tests/phpunit/testcases/replies/template/status.php
@@ -37,6 +37,40 @@ class BBP_Tests_Repliess_Template_Status extends BBP_UnitTestCase {
 	}
 
 	/**
+	 * @covers ::bbp_get_draft_new_reply_statuses
+	 */
+	public function test_bbp_get_draft_new_reply_statuses() {
+
+		$expected = array( 'auto-draft', 'draft', 'new' );
+
+		$this->assertEquals( $expected, bbp_get_draft_new_reply_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_public_reply_statuses
+	 */
+	public function test_bbp_get_public_reply_statuses() {
+
+		$expected = array( bbp_get_public_status_id() );
+
+		$this->assertEquals( $expected, bbp_get_public_reply_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_moderated_reply_statuses
+	 */
+	public function test_bbp_get_moderated_reply_statuses() {
+
+		$expected = array(
+			bbp_get_pending_status_id(),
+			bbp_get_spam_status_id(),
+			bbp_get_trash_status_id(),
+		);
+
+		$this->assertEquals( $expected, bbp_get_moderated_reply_statuses() );
+	}
+
+	/**
 	 * @covers ::bbp_is_reply_published
 	 */
 	public function test_bbp_is_reply_published() {
diff --git tests/phpunit/testcases/topics/functions/counts.php tests/phpunit/testcases/topics/functions/counts.php
index f2296af..21befaf 100644
--- tests/phpunit/testcases/topics/functions/counts.php
+++ tests/phpunit/testcases/topics/functions/counts.php
@@ -13,7 +13,9 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 	 * Generic function to test the topics counts with a new reply
 	 */
 	public function test_bbp_topic_new_reply_counts() {
-		remove_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10 );
+
+		// Remove the transitioned new action so we can simulate a new reply.
+		remove_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new' );
 
 		$u  = $this->factory->user->create();
 		$u2 = $this->factory->user->create();
@@ -34,11 +36,8 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 			),
 		) );
 
-		// Don't attempt to send an email. This is for speed and PHP errors.
-		remove_action( 'bbp_new_reply', 'bbp_notify_topic_subscribers', 11, 5 );
-
-		// Simulate the 'bbp_new_reply' action.
-		do_action( 'bbp_new_reply', $r1, $t, $f, false, bbp_get_current_user_id() );
+		// Simulate the 'bbp_transitioned_reply_status_new' action.
+		do_action( 'bbp_transitioned_reply_status_new', $r1 );
 
 		$count = bbp_get_topic_reply_count( $t, true );
 		$this->assertSame( 1, $count );
@@ -58,8 +57,8 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 			),
 		) );
 
-		// Simulate the 'bbp_new_topic' action.
-		do_action( 'bbp_new_reply', $r2, $t, $f, false, $u2 );
+		// Simulate the 'bbp_transitioned_reply_status_new' action.
+		do_action( 'bbp_transitioned_reply_status_new', $r2 );
 
 		$count = bbp_get_topic_reply_count( $t, true );
 		$this->assertSame( 2, $count );
@@ -70,9 +69,8 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 		$count = bbp_get_topic_voice_count( $t, true );
 		$this->assertSame( 2, $count );
 
-		// Re-add removed actions.
-		add_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10, 2 );
-		add_action( 'bbp_new_reply',    'bbp_notify_topic_subscribers',   11, 5 );
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new' );
 	}
 
 	/**
diff --git tests/phpunit/testcases/topics/functions/status.php tests/phpunit/testcases/topics/functions/status.php
index 2f56fde..c80991e 100644
--- tests/phpunit/testcases/topics/functions/status.php
+++ tests/phpunit/testcases/topics/functions/status.php
@@ -419,4 +419,200 @@ class BBP_Tests_Topics_Functions_Status extends BBP_UnitTestCase {
 			'This test has not been implemented yet.'
 		);
 	}
+
+	/**
+	 * @covers ::bbp_transition_topic_status
+	 */
+	public function test_bbp_transition_topic_status() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transition_topic_status(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_topic( $t )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transition_topic_status_new_public
+	 */
+	public function test_bbp_transition_topic_status_new_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transition_topic_status_new_public(
+			bbp_get_public_status_id(),
+			'new',
+			bbp_get_topic( $t )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_public', bbp_get_post_transitioned_status( $t ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_topic_status_new_moderated
+	 */
+	public function test_bbp_transition_topic_status_new_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transition_topic_status_new_moderated(
+			bbp_get_pending_status_id(),
+			'new',
+			bbp_get_topic( $t )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'new_moderated', bbp_get_post_transitioned_status( $t ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_topic_status_public
+	 */
+	public function test_bbp_transition_topic_status_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transition_topic_status_public(
+			bbp_get_public_status_id(),
+			bbp_get_pending_status_id(),
+			bbp_get_topic( $t )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'public', bbp_get_post_transitioned_status( $t ) );
+	}
+
+	/**
+	 * @covers ::bbp_transition_topic_status_moderated
+	 */
+	public function test_bbp_transition_topic_status_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transition_topic_status_moderated(
+			bbp_get_pending_status_id(),
+			bbp_get_public_status_id(),
+			bbp_get_topic( $t )
+		);
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+
+		$this->assertEquals( 'moderated', bbp_get_post_transitioned_status( $t ) );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_topic_status_new_public
+	 */
+	public function test_bbp_transitioned_topic_status_new_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transitioned_topic_status_new_public( $t );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_topic_status_new_moderated
+	 */
+	public function test_bbp_transitioned_topic_status_new_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'post_status' => bbp_get_pending_status_id(),
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		$result = bbp_transitioned_topic_status_new_moderated( $t );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_topic_status_public
+	 */
+	public function test_bbp_transitioned_topic_status_public() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'post_status' => bbp_get_pending_status_id(),
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		bbp_approve_topic( $t );
+
+		$result = bbp_transitioned_topic_status_public( $t );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @covers ::bbp_transitioned_topic_status_moderated
+	 */
+	public function test_bbp_transitioned_topic_status_moderated() {
+		$f = $this->factory->forum->create();
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+			'topic_meta'  => array(
+				'forum_id' => $f,
+			),
+		) );
+
+		bbp_unapprove_topic( $t );
+
+		$result = bbp_transitioned_topic_status_moderated( $t );
+
+		// A true result means the action was added, as failures return false.
+		$this->assertTrue( $result );
+	}
 }
diff --git tests/phpunit/testcases/topics/template/status.php tests/phpunit/testcases/topics/template/status.php
index 3dc3ece..da2779f 100644
--- tests/phpunit/testcases/topics/template/status.php
+++ tests/phpunit/testcases/topics/template/status.php
@@ -54,6 +54,40 @@ class BBP_Tests_Topics_Template_Status extends BBP_UnitTestCase {
 	}
 
 	/**
+	 * @covers ::bbp_get_draft_new_topic_statuses
+	 */
+	public function test_bbp_get_draft_new_topic_statuses() {
+
+		$expected = array( 'auto-draft', 'draft', 'new' );
+
+		$this->assertEquals( $expected, bbp_get_draft_new_topic_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_public_topic_statuses
+	 */
+	public function test_bbp_get_public_topic_statuses() {
+
+		$expected = array( bbp_get_public_status_id(), bbp_get_closed_status_id() );
+
+		$this->assertEquals( $expected, bbp_get_public_topic_statuses() );
+	}
+
+	/**
+	 * @covers ::bbp_get_moderated_topic_statuses
+	 */
+	public function test_bbp_get_moderated_topic_statuses() {
+
+		$expected = array(
+			bbp_get_pending_status_id(),
+			bbp_get_spam_status_id(),
+			bbp_get_trash_status_id(),
+		);
+
+		$this->assertEquals( $expected, bbp_get_moderated_topic_statuses() );
+	}
+
+	/**
 	 * @covers ::bbp_is_topic_closed
 	 * @todo   Implement test_bbp_is_topic_closed().
 	 */
diff --git tests/phpunit/testcases/users/functions/counts.php tests/phpunit/testcases/users/functions/counts.php
index 190a9cd..30fd2ec 100644
--- tests/phpunit/testcases/users/functions/counts.php
+++ tests/phpunit/testcases/users/functions/counts.php
@@ -266,6 +266,10 @@ class BBP_Tests_Users_Functions_Counts extends BBP_UnitTestCase {
 	 * @covers ::bbp_increase_user_topic_count
 	 */
 	public function test_bbp_increase_user_topic_count() {
+
+		// Remove the transitioned new action so we manually manipulate counts.
+		remove_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new_public', 20 );
+
 		$u = $this->factory->user->create();
 		$int_value = 3;
 		$integer = true;
@@ -283,12 +287,19 @@ class BBP_Tests_Users_Functions_Counts extends BBP_UnitTestCase {
 
 		$count = bbp_get_user_topic_count( $u, $integer );
 		$this->assertSame( $int_value + 1, $count );
+
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new_public', 20 );
 	}
 
 	/**
 	 * @covers ::bbp_increase_user_reply_count
 	 */
 	public function test_bbp_increase_user_reply_count() {
+
+		// Remove the transitioned new action so we manually manipulate counts.
+		remove_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new_public', 20 );
+
 		$u = $this->factory->user->create();
 		$int_value = 3;
 		$integer = true;
@@ -312,12 +323,19 @@ class BBP_Tests_Users_Functions_Counts extends BBP_UnitTestCase {
 
 		$count = bbp_get_user_reply_count( $u, $integer );
 		$this->assertSame( $int_value, $count );
+
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new_public', 20 );
 	}
 
 	/**
 	 * @covers ::bbp_decrease_user_topic_count
 	 */
 	public function test_bbp_decrease_user_topic_count() {
+
+		// Remove the transitioned new action so we manually manipulate counts.
+		remove_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new_public', 20 );
+
 		$u = $this->factory->user->create();
 		$int_value = 3;
 		$integer = true;
@@ -342,12 +360,19 @@ class BBP_Tests_Users_Functions_Counts extends BBP_UnitTestCase {
 
 		$count = bbp_get_user_topic_count( $u, $integer );
 		$this->assertSame( $int_value - 2, $count );
+
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_topic', 'bbp_transitioned_topic_status_new_public', 20 );
 	}
 
 	/**
 	 * @covers ::bbp_decrease_user_reply_count
 	 */
 	public function test_bbp_decrease_user_reply_count() {
+
+		// Remove the transitioned new action so we manually manipulate counts.
+		remove_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new_public', 20 );
+
 		$u = $this->factory->user->create();
 		$int_value = 3;
 		$integer = true;
@@ -378,5 +403,8 @@ class BBP_Tests_Users_Functions_Counts extends BBP_UnitTestCase {
 
 		$count = bbp_get_user_reply_count( $u, $integer );
 		$this->assertSame( $int_value - 2, $count );
+
+		// Re-add the transitioned new action.
+		add_action( 'bbp_insert_reply', 'bbp_transitioned_reply_status_new_public', 20 );
 	}
 }
