Index: src/includes/common/functions.php
--- src/includes/common/functions.php
+++ src/includes/common/functions.php
@@ -2633,3 +2633,57 @@
 	// Filter & return
 	return (bool) apply_filters( 'bbp_is_title_too_long', $result, $title, $max, $len );
 }
+
+/** Revisions *****************************************************************/
+
+/**
+ * Update a forum/topic/reply without creating a subsequent revision.
+ *
+ * This is particularly handy when toggling specific attributes (like statuses)
+ * where you _do_ want all of the related hooks to fire but you _do not_ want to
+ * generate a new revision when doing so.
+ *
+ * @since 2.6.7 bbPress (r7188)
+ *
+ * @param array $post
+ * @return mixed
+ */
+function bbp_update_post_without_revision( $post = array() ) {
+
+	// Default return value
+	$retval = false;
+
+	// Default post data
+	$to_save = array();
+
+	// Maybe cast to array
+	if ( is_object( $post ) || is_array( $post ) ) {
+		$to_save = (array) $post;
+	}
+
+	// Bail if no "post_type" in array
+	if ( ! empty( $to_save['post_type'] ) ) {
+
+		// Set a post type variable so code is cleaner below
+		$post_type = $to_save['post_type'];
+
+		// Are revisions supported?
+		$supported = post_type_supports( $post_type, 'revisions' );
+
+		// Maybe remove revision support
+		if ( true === $supported ) {
+			remove_post_type_support( $post_type, 'revisions' );
+		}
+
+		// Update the post
+		$retval = wp_update_post( $to_save );
+
+		// Toggle revisions back on
+		if ( true === $supported ) {
+			add_post_type_support( $post_type, 'revisions' );
+		}
+	}
+
+	// Filter & return
+	return apply_filters( 'bbp_update_post_without_revision', $retval, $post );
+}
Index: src/includes/core/template-functions.php
--- src/includes/core/template-functions.php
+++ src/includes/core/template-functions.php
@@ -722,9 +722,6 @@
 			$posts_query->bbp_is_404            = false;
 		}

-		// We save post revisions on our own
-		remove_action( 'pre_post_update', 'wp_save_post_revision' );
-
 	// Topic tag page
 	} elseif ( bbp_is_topic_tag() ) {
 		$posts_query->set( 'bbp_topic_tag',  get_query_var( 'term' )   );
Index: src/includes/extend/buddypress/activity.php
--- src/includes/extend/buddypress/activity.php
+++ src/includes/extend/buddypress/activity.php
@@ -211,9 +211,9 @@
 	 */
 	private function record_activity( $args = array() ) {

-		// Default activity args
+		// Parse arguments
 		$activity = bbp_parse_args( $args, array(
-			'id'                => null,
+			'id'                => false,
 			'user_id'           => bbp_get_current_user_id(),
 			'type'              => '',
 			'action'            => '',
@@ -227,7 +227,15 @@
 		), 'record_activity' );

 		// Add the activity
-		return bp_activity_add( $activity );
+		$activity_id = bp_activity_add( $activity );
+
+		// Add the activity entry ID as a meta value to the topic
+		if ( ! empty( $activity_id ) && ! empty( $activity['item_id'] ) ) {
+			update_post_meta( $activity['item_id'], '_bbp_activity_id', $activity_id );
+		}
+
+		// Return the activity ID
+		return $activity_id;
 	}

 	/**
@@ -235,13 +243,13 @@
 	 *
 	 * @since 2.0.0 bbPress (r3395)
 	 *
-	 * @param  array $args Array of arguments for bp_activity_add()
+	 * @param  array $args Array of arguments for bp_activity_delete_by_item_id()
 	 *
 	 * @return int   Activity ID if successful, false if not
 	 */
 	public function delete_activity( $args = array() ) {

-		// Default activity args
+		// Parse arguments
 		$activity = bbp_parse_args( $args, array(
 			'item_id'           => false,
 			'component'         => $this->component,
@@ -257,6 +265,8 @@
 	/**
 	 * Check for an existing activity stream entry for a given post_id
 	 *
+	 * @since 2.0.0 bbPress (r3395)
+	 *
 	 * @param int $post_id ID of the topic or reply
 	 * @return int if an activity id is verified, false if not
 	 */
@@ -267,13 +277,19 @@

 		// Bail if no activity ID is in post meta
 		if ( empty( $activity_id ) ) {
-			return null;
+			return false;
 		}

-		// Get the activity stream item, bail if it doesn't exist
+		// Get the activity stream item
 		$existing = new BP_Activity_Activity( $activity_id );
+
+		// Bail if activity does not exist
 		if ( empty( $existing->component ) ) {
-			return null;
+
+			// Remove orphaned meta data
+			delete_post_meta( $post_id, '_bbp_activity_id' );
+
+			return false;
 		}

 		// Return the activity ID since we've verified the connection
@@ -348,6 +364,9 @@
 	/**
 	 * Record an activity stream entry when a topic is created or updated
 	 *
+	 * Despite the method name, it is also used when Editing a Topic, which will
+	 * update the subsequent related activity stream entry.
+	 *
 	 * @since 2.0.0 bbPress (r3395)
 	 *
 	 * @param int $topic_id
@@ -402,9 +421,14 @@
 		$activity_action  = apply_filters( 'bbp_activity_topic_create',         $activity_text, $user_id,   $topic_id,   $forum_id );
 		$activity_content = apply_filters( 'bbp_activity_topic_create_excerpt', $topic_content                                     );

+		// ID, time, and visibility
+		$activity_id      = $this->get_activity_id( $topic_id );
+		$recorded_time    = get_post_time( 'Y-m-d H:i:s', true, $topic_id );
+		$hide_sitewide    = ! bbp_is_forum_public( $forum_id, false );
+
 		// Compile and record the activity stream results
-		$activity_id = $this->record_activity( array(
-			'id'                => $this->get_activity_id( $topic_id ),
+		$this->record_activity( array(
+			'id'                => $activity_id,
 			'user_id'           => $user_id,
 			'action'            => $activity_action,
 			'content'           => $activity_content,
@@ -412,14 +436,9 @@
 			'type'              => $this->topic_create,
 			'item_id'           => $topic_id,
 			'secondary_item_id' => $forum_id,
-			'recorded_time'     => get_post_time( 'Y-m-d H:i:s', true, $topic_id ),
-			'hide_sitewide'     => ! bbp_is_forum_public( $forum_id, false )
+			'recorded_time'     => $recorded_time,
+			'hide_sitewide'     => $hide_sitewide
 		) );
-
-		// Add the activity entry ID as a meta value to the topic
-		if ( ! empty( $activity_id ) ) {
-			update_post_meta( $topic_id, '_bbp_activity_id', $activity_id );
-		}
 	}

 	/**
@@ -452,11 +471,6 @@
 			return;
 		}

-		// Bail early if revisions are off
-		if ( ! bbp_allow_revisions() || ! post_type_supports( bbp_get_topic_post_type(), 'revisions' ) ) {
-			return;
-		}
-
 		$topic_id = bbp_get_topic_id( $topic_id );

 		// Bail early if topic is by anonymous user
@@ -480,8 +494,11 @@
 	/** Replies ***************************************************************/

 	/**
-	 * Record an activity stream entry when a reply is created
+	 * Record an activity stream entry when a reply is created or updated
 	 *
+	 * Despite the method name, it is also used when Editing a Reply, which will
+	 * update the subsequent related activity stream entry.
+	 *
 	 * @since 2.0.0 bbPress (r3395)
 	 *
 	 * @param int $topic_id
@@ -540,9 +557,14 @@
 		$activity_action  = apply_filters( 'bbp_activity_reply_create',         $activity_text, $user_id, $reply_id,  $topic_id );
 		$activity_content = apply_filters( 'bbp_activity_reply_create_excerpt', $reply_content                                  );

+		// ID, time, and visibility
+		$activity_id      = $this->get_activity_id( $reply_id );
+		$recorded_time    = get_post_time( 'Y-m-d H:i:s', true, $reply_id );
+		$hide_sitewide    = ! bbp_is_forum_public( $forum_id, false );
+
 		// Compile and record the activity stream results
-		$activity_id = $this->record_activity( array(
-			'id'                => $this->get_activity_id( $reply_id ),
+		$this->record_activity( array(
+			'id'                => $activity_id,
 			'user_id'           => $user_id,
 			'action'            => $activity_action,
 			'content'           => $activity_content,
@@ -550,14 +572,9 @@
 			'type'              => $this->reply_create,
 			'item_id'           => $reply_id,
 			'secondary_item_id' => $topic_id,
-			'recorded_time'     => get_post_time( 'Y-m-d H:i:s', true, $reply_id ),
-			'hide_sitewide'     => ! bbp_is_forum_public( $forum_id, false )
+			'recorded_time'     => $recorded_time,
+			'hide_sitewide'     => $hide_sitewide
 		) );
-
-		// Add the activity entry ID as a meta value to the reply
-		if ( ! empty( $activity_id ) ) {
-			update_post_meta( $reply_id, '_bbp_activity_id', $activity_id );
-		}
 	}

 	/**
@@ -583,18 +600,13 @@
 	 * @param obj $post
 	 * @return Bail early if not a reply, or reply is by anonymous user
 	 */
-	public function reply_update( $reply_id, $post ) {
+	public function reply_update( $reply_id = 0, $post = null) {

 		// Bail early if not a reply
 		if ( get_post_type( $post ) !== bbp_get_reply_post_type() ) {
 			return;
 		}

-		// Bail early if revisions are off
-		if ( ! bbp_allow_revisions() || ! post_type_supports( bbp_get_reply_post_type(), 'revisions' ) ) {
-			return;
-		}
-
 		$reply_id = bbp_get_reply_id( $reply_id );

 		// Bail early if reply is by anonymous user
Index: src/includes/forums/functions.php
--- src/includes/forums/functions.php
+++ src/includes/forums/functions.php
@@ -507,8 +507,8 @@
 		'post_parent'  => $forum_parent_id
 	) );

-	// Insert forum
-	$forum_id = wp_update_post( $forum_data );
+	// Update forum
+	$forum_id = bbp_update_post_without_revision( $forum_data );

 	/** No Errors *************************************************************/

Index: src/includes/replies/functions.php
--- src/includes/replies/functions.php
+++ src/includes/replies/functions.php
@@ -504,7 +504,6 @@
 	}

 	// Define local variable(s)
-	$revisions_removed = false;
 	$reply = $reply_id = $reply_to = $reply_author = $topic_id = $forum_id = 0;
 	$reply_title = $reply_content = $reply_edit_reason = $terms = '';
 	$anonymous_data = array();
@@ -693,21 +692,9 @@
 		'post_type'    => bbp_get_reply_post_type()
 	) );

-	// Toggle revisions to avoid duplicates
-	if ( post_type_supports( bbp_get_reply_post_type(), 'revisions' ) ) {
-		$revisions_removed = true;
-		remove_post_type_support( bbp_get_reply_post_type(), 'revisions' );
-	}
+	// Update reply
+	$reply_id = bbp_update_post_without_revision( $reply_data );

-	// Insert reply
-	$reply_id = wp_update_post( $reply_data );
-
-	// Toggle revisions back on
-	if ( true === $revisions_removed ) {
-		$revisions_removed = false;
-		add_post_type_support( bbp_get_reply_post_type(), 'revisions' );
-	}
-
 	/** Topic Tags ************************************************************/

 	// Just in time manipulation of reply terms before being edited
@@ -1742,12 +1729,9 @@
 	// Set post status to spam
 	$reply->post_status = bbp_get_spam_status_id();

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
+	// Update reply
+	$reply_id = bbp_update_post_without_revision( $reply );

-	// Update the reply
-	$reply_id = wp_update_post( $reply );
-
 	// Execute post spam code
 	do_action( 'bbp_spammed_reply', $reply_id );

@@ -1790,12 +1774,9 @@
 	// Delete pre spam meta
 	delete_post_meta( $reply_id, '_bbp_spam_meta_status' );

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
+	// Update reply
+	$reply_id = bbp_update_post_without_revision( $reply );

-	// Update the reply
-	$reply_id = wp_update_post( $reply );
-
 	// Execute post unspam code
 	do_action( 'bbp_unspammed_reply', $reply_id );

@@ -1836,11 +1817,8 @@
 	// Set post date GMT - prevents post_date override in wp_update_post()
 	$reply->post_date_gmt = get_gmt_from_date( $reply->post_date );

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
-
 	// Update reply
-	$reply_id = wp_update_post( $reply );
+	$reply_id = bbp_update_post_without_revision( $reply );

 	// Execute post pending code
 	do_action( 'bbp_approved_reply', $reply_id );
@@ -1879,11 +1857,8 @@
 	// Set pending status
 	$reply->post_status = $status;

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
-
 	// Update reply
-	$reply_id = wp_update_post( $reply );
+	$reply_id = bbp_update_post_without_revision( $reply );

 	// Execute post open code
 	do_action( 'bbp_unapproved_reply', $reply_id );
Index: src/includes/topics/functions.php
--- src/includes/topics/functions.php
+++ src/includes/topics/functions.php
@@ -418,7 +418,6 @@
 	}

 	// Define local variable(s)
-	$revisions_removed = false;
 	$topic = $topic_id = $topic_author = $forum_id = 0;
 	$topic_title = $topic_content = $topic_edit_reason = '';
 	$anonymous_data = array();
@@ -626,21 +625,9 @@
 		'tax_input'    => $terms,
 	) );

-	// Toggle revisions to avoid duplicates
-	if ( post_type_supports( bbp_get_topic_post_type(), 'revisions' ) ) {
-		$revisions_removed = true;
-		remove_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
+	// Update topic
+	$topic_id = bbp_update_post_without_revision( $topic_data );

-	// Insert topic
-	$topic_id = wp_update_post( $topic_data );
-
-	// Toggle revisions back on
-	if ( true === $revisions_removed ) {
-		$revisions_removed = false;
-		add_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
-
 	/** No Errors *************************************************************/

 	if ( ! empty( $topic_id ) && ! is_wp_error( $topic_id ) ) {
@@ -2815,21 +2802,9 @@
 	// Set closed status
 	$topic->post_status = $status;

-	// Toggle revisions off as we are not altering content
-	if ( post_type_supports( bbp_get_topic_post_type(), 'revisions' ) ) {
-		$revisions_removed = true;
-		remove_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
-
 	// Update topic
-	$topic_id = wp_update_post( $topic );
+	$topic_id = bbp_update_post_without_revision( $topic );

-	// Toggle revisions back on
-	if ( true === $revisions_removed ) {
-		$revisions_removed = false;
-		add_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
-
 	// Execute post close code
 	do_action( 'bbp_closed_topic', $topic_id );

@@ -2869,27 +2844,15 @@
 		$topic_status = bbp_get_public_status_id();
 	}

-	// Set previous status
-	$topic->post_status = $topic_status;
-
 	// Remove old status meta
 	delete_post_meta( $topic_id, '_bbp_status' );

-	// Toggle revisions off as we are not altering content
-	if ( post_type_supports( bbp_get_topic_post_type(), 'revisions' ) ) {
-		$revisions_removed = true;
-		remove_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
+	// Set previous status
+	$topic->post_status = $topic_status;

 	// Update topic
-	$topic_id = wp_update_post( $topic );
+	$topic_id = bbp_update_post_without_revision( $topic );

-	// Toggle revisions back on
-	if ( true === $revisions_removed ) {
-		$revisions_removed = false;
-		add_post_type_support( bbp_get_topic_post_type(), 'revisions' );
-	}
-
 	// Execute post open code
 	do_action( 'bbp_opened_topic', $topic_id );

@@ -2933,12 +2896,9 @@
 	// Empty the topic of its tags
 	$topic->tax_input = bbp_spam_topic_tags( $topic_id );

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
+	// Update topic
+	$topic_id = bbp_update_post_without_revision( $topic );

-	// Update the topic
-	$topic_id = wp_update_post( $topic );
-
 	// Execute post spam code
 	do_action( 'bbp_spammed_topic', $topic_id );

@@ -3077,12 +3037,9 @@
 	// Delete pre spam meta
 	delete_post_meta( $topic_id, '_bbp_spam_meta_status' );

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
+	// Update topic
+	$topic_id = bbp_update_post_without_revision( $topic );

-	// Update the topic
-	$topic_id = wp_update_post( $topic );
-
 	// Execute post unspam code
 	do_action( 'bbp_unspammed_topic', $topic_id );

@@ -3238,11 +3195,8 @@
 	// Set post date GMT - prevents post_date override in wp_update_post()
 	$topic->post_date_gmt = get_gmt_from_date( $topic->post_date );

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
-
 	// Update topic
-	$topic_id = wp_update_post( $topic );
+	$topic_id = bbp_update_post_without_revision( $topic );

 	// Execute post pending code
 	do_action( 'bbp_approved_topic', $topic_id );
@@ -3281,11 +3235,8 @@
 	// Set pending status
 	$topic->post_status = $status;

-	// No revisions
-	remove_action( 'pre_post_update', 'wp_save_post_revision' );
-
 	// Update topic
-	$topic_id = wp_update_post( $topic );
+	$topic_id = bbp_update_post_without_revision( $topic );

 	// Execute post open code
 	do_action( 'bbp_unapproved_topic', $topic_id );
