Index: bp-activity/admin/css/admin.css
===================================================================
--- bp-activity/admin/css/admin.css
+++ bp-activity/admin/css/admin.css
@@ -75,3 +75,6 @@
 #bp-activities-primaryid {
 	margin-bottom: 1em;
 }
+.column-action {
+	width: 12%;
+}
\ No newline at end of file
Index: bp-activity/admin/css/admin.min.css
===================================================================
--- bp-activity/admin/css/admin.min.css
+++ bp-activity/admin/css/admin.min.css
@@ -1 +1 @@
-.akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:left;margin-right:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-left:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:white}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}
\ No newline at end of file
+.akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:left;margin-right:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-left:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:white}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}.column-action{width:12%}
\ No newline at end of file
Index: bp-activity/bp-activity-admin.php
===================================================================
--- bp-activity/bp-activity-admin.php
+++ bp-activity/bp-activity-admin.php
@@ -458,22 +458,12 @@
 
 		// Activity type
 		if ( ! empty( $_POST['bp-activities-type'] ) ) {
-			$actions  = array();
-
-			// Walk through the registered actions, and build an array of actions/values.
-			foreach ( $bp->activity->actions as $action ) {
-				$action = array_values( (array) $action );
-
-				for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
-					$actions[] = $action[$i]['key'];
-			}
-
-			// This was a mis-named activity type from before BP 1.6
-			unset( $actions['friends_register_activity_action'] );
+			$actions = bp_activity_admin_get_activity_actions();
 
 			// Check that the new type is a registered activity type
-			if ( in_array( $_POST['bp-activities-type'], $actions ) )
+			if ( in_array( $_POST['bp-activities-type'], $actions ) ) {
 				$activity->type = $_POST['bp-activities-type'];
+			}
 		}
 
 		// Activity timestamp
@@ -736,26 +726,24 @@
 }
 
 /**
- * Activity type metabox for the Activity admin edit screen
+ * Get flattened array of all registered activity actions.
  *
- * @since BuddyPress (1.6.0)
+ * Format is [activity_type] => Pretty name for activity type.
  *
- * @global object $bp BuddyPress global settings.
+ * @since BuddyPress (2.0.0)
  *
- * @param object $item Activity item.
+ * @return array
  */
-function bp_activity_admin_edit_metabox_type( $item ) {
-	global $bp;
-
+function bp_activity_admin_get_activity_actions() {
 	$actions  = array();
-	$selected = $item->type;
 
 	// Walk through the registered actions, and build an array of actions/values.
-	foreach ( $bp->activity->actions as $action ) {
+	foreach ( buddypress()->activity->actions as $action ) {
 		$action = array_values( (array) $action );
 
-		for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
+		for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
 			$actions[ $action[$i]['key'] ] = $action[$i]['value'];
+		}
 	}
 
 	// This was a mis-named activity type from before BP 1.6
@@ -764,6 +752,22 @@
 	// Sort array by the human-readable value
 	natsort( $actions );
 
+	return $actions;
+}
+
+/**
+ * Activity type metabox for the Activity admin edit screen
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param object $item Activity item.
+ */
+function bp_activity_admin_edit_metabox_type( $item ) {
+	$actions  = bp_activity_admin_get_activity_actions();
+	$selected = $item->type;
+
 	// If the activity type is not registered properly (eg, a plugin has
 	// not called bp_activity_set_action()), add the raw type to the end
 	// of the list
@@ -974,6 +978,9 @@
 	 */
 	public function __construct() {
 
+		// See if activity commenting is enabled for blog / forum activity items
+		$this->disable_blogforum_comments = bp_disable_blogforum_comments();
+
 		// Define singular and plural labels, as well as whether we support AJAX.
 		parent::__construct( array(
 			'ajax'     => false,
@@ -1217,6 +1224,7 @@
 			'cb'       => '<input name type="checkbox" />',
 			'author'   => __( 'Author', 'buddypress' ),
 			'comment'  => __( 'Activity', 'buddypress' ),
+			'action'   => __( 'Action', 'buddypress' ),
 			'response' => __( 'In Response To', 'buddypress' ),
 		);
 	}
@@ -1300,6 +1308,25 @@
 	}
 
 	/**
+	 * Action column markup.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @see WP_List_Table::single_row_columns()
+	 *
+	 * @param array $item A singular item (one full row).
+	 */
+	function column_action( $item ) {
+		$actions = bp_activity_admin_get_activity_actions();
+
+		if ( isset( $actions[ $item['type'] ] ) ) {
+			echo $actions[ $item['type'] ];
+		} else {
+			printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
+		}
+	}
+
+	/**
 	 * Content column, and "quick admin" rollover actions.
 	 *
 	 * Called "comment" in the CSS so we can re-use some WP core CSS.
@@ -1338,7 +1365,11 @@
 
 		// Reply - javascript only; implemented by AJAX.
 		if ( 'spam' != $item_status ) {
-			$actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
+			if ( $this->can_comment( $item ) ) {
+				$actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
+			} else {
+				$actions['reply'] = sprintf( '<span class="form-input-tip" title="%s">%s</span>', __( 'Replies are disabled for this activity item', 'buddypress' ), __( 'Replies disabled', 'buddypress' ) );
+			}
 
 			// Edit
 			$actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
@@ -1445,6 +1476,52 @@
 	}
 
 	/**
+	 * Checks if an activity item can be replied to.
+	 *
+	 * This method merges functionality from {@link bp_activity_can_comment()} and
+	 * {@link bp_blogs_disable_activity_commenting()}.  This is done because the activity
+	 * list table doesn't use a BuddyPress activity loop, which prevents those
+	 * functions from working as intended.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $item An array version of the BP_Activity_Activity object.
+	 * @return bool
+	 */
+	protected function can_comment( $item  ) {
+		$can_comment = true;
+
+		if ( $this->disable_blogforum_comments ) {
+			switch ( $item['type'] ) {
+				case 'new_blog_post' :
+				case 'new_blog_comment' :
+				case 'new_forum_topic' :
+				case 'new_forum_post' :
+					$can_comment = false;
+					break;
+			}
+
+		// activity comments require special checking
+		} elseif ( 'activity_comment' == $item['type'] ) {
+			// blogs
+			if ( bp_is_active( 'blogs' ) ) {
+				// grab the parent activity entry
+				$parent_activity = new BP_Activity_Activity( $item['item_id'] );
+
+				// fetch blog post comment depth and if the blog post's comments are open
+				bp_blogs_setup_activity_loop_globals( $parent_activity );
+
+				// check if the activity item can be replied to
+				if ( false === bp_blogs_can_comment_reply( true, $item ) ) {
+					$can_comment = false;
+				}
+			}
+		}
+
+		return apply_filters( 'bp_activity_list_table_can_comment', $can_comment );
+	}
+
+	/**
 	 * Flatten the activity array.
 	 *
 	 * In some cases, BuddyPress gives us a structured tree of activity
Index: bp-activity/bp-activity-functions.php
===================================================================
--- bp-activity/bp-activity-functions.php
+++ bp-activity/bp-activity-functions.php
@@ -1522,8 +1522,9 @@
 	 * You may want to hook into this filter if you want to override this function and
 	 * handle the deletion of child comments differently. Make sure you return false.
 	 */
-	if ( !apply_filters( 'bp_activity_delete_comment_pre', true, $activity_id, $comment_id ) )
-		return false;
+	if ( ! apply_filters( 'bp_activity_delete_comment_pre', true, $activity_id, $comment_id ) ) {
+		return true;
+	}
 
 	// Delete any children of this comment.
 	bp_activity_delete_children( $activity_id, $comment_id );
Index: bp-activity/bp-activity-template.php
===================================================================
--- bp-activity/bp-activity-template.php
+++ bp-activity/bp-activity-template.php
@@ -2972,6 +2972,32 @@
 	}
 
 /**
+ * Recurse through all activity comments and return the activity comment IDs.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $activity Array of activities generated from {@link bp_activity_get()}.
+ * @return array
+ */
+function bp_activity_recurse_comments_activity_ids( $activity = array(), $activity_ids = array() ) {
+	if ( is_array( $activity ) && ! empty( $activity['activities'] ) ) {
+		$activity = $activity['activities'][0];	
+	}
+
+	if ( ! empty( $activity->children ) ) {
+		foreach ($activity->children as $child ) {
+			$activity_ids[] = $child->id;
+
+			if( ! empty( $child->children ) ) {
+				$activity_ids = bp_activity_recurse_comments_activity_ids( $child, $activity_ids );
+			}
+		}
+	}
+
+	return $activity_ids;
+}
+
+/**
  * Output the mentionname for the displayed user.
  *
  * @since BuddyPress (1.9.0)
Index: bp-blogs/bp-blogs-activity.php
===================================================================
--- bp-blogs/bp-blogs-activity.php
+++ bp-blogs/bp-blogs-activity.php
@@ -345,3 +345,506 @@
 		'secondary_item_id' => $secondary_item_id
 	) );
 }
+
+/**
+ * Check if a blog post's activity item should be closed from commenting.
+ *
+ * This mirrors the {@link comments_open()} and {@link _close_comments_for_old_post()}
+ * functions, but for use with the BuddyPress activity stream to be as
+ * lightweight as possible.
+ *
+ * By lightweight, we actually mirror a few of the blog's commenting settings
+ * to blogmeta and checks the values in blogmeta instead.  This is to prevent
+ * multiple {@link switch_to_blog()} calls in the activity stream.
+ *
+ * @param object $activity The BP_Activity_Activity object
+ * @return bool
+ */
+function bp_blogs_comments_open( $activity ) {
+	$open = true;
+
+	$blog_id = $activity->item_id;
+
+	// see if we've mirrored the close comments option before
+	$days_old = bp_blogs_get_blogmeta( $blog_id, 'close_comments_days_old' );
+
+	// we've never cached these items before, so do it now
+	if ( '' === $days_old ) {
+		switch_to_blog( $blog_id );
+
+		// use comments_open()
+		remove_filter( 'comments_open', 'bp_comments_open', 10, 2 );
+		$open = comments_open( $activity->secondary_item_id );
+		add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
+
+		// might as well mirror values to blogmeta since we're here!
+		$thread_depth = get_option( 'thread_comments' );
+		if ( ! empty( $thread_depth ) ) {
+			$thread_depth = get_option( 'thread_comments_depth' );
+		} else {
+			// perhaps filter this?
+			$thread_depth = 1;
+		}
+
+		bp_blogs_update_blogmeta( $blog_id, 'close_comments_for_old_posts', get_option( 'close_comments_for_old_posts' ) );
+		bp_blogs_update_blogmeta( $blog_id, 'close_comments_days_old',      get_option( 'close_comments_days_old' ) );
+		bp_blogs_update_blogmeta( $blog_id, 'thread_comments_depth',        $thread_depth );
+
+		restore_current_blog();
+
+	// check blogmeta and manually check activity item
+	// basically a copy of _close_comments_for_old_post()
+	} else {
+
+		// comments are closed
+		if ( 'closed' == bp_activity_get_meta( $activity->id, 'post_comment_status' ) ) {
+			return false;
+		}
+
+		if ( ! bp_blogs_get_blogmeta( $blog_id, 'close_comments_for_old_posts' ) ) {
+			return $open;
+		}
+
+		$days_old = (int) $days_old;
+		if ( ! $days_old ) {
+			return $open;
+		}
+
+		/* commenting out for now - needs some more thought...
+		   should we add the post type to activity meta?
+
+		$post = get_post($post_id);
+
+		// This filter is documented in wp-includes/comment.php
+		$post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) );
+		if ( ! in_array( $post->post_type, $post_types ) )
+			return $open;
+		*/
+
+		if ( time() - strtotime( $activity->date_recorded ) > ( $days_old * DAY_IN_SECONDS ) ) {
+			return false;
+		}
+
+		return $open;
+	}
+
+	return $open;
+}
+
+/** POST COMMENT SYNCHRONIZATION ****************************************/
+
+/**
+ * Syncs activity comments and posts them back as blog comments.
+ *
+ * Note: This is only a one-way sync - activity comments -> blog comment.
+ *
+ * For blog post -> activity comment, see {@link bp_blogs_record_comment()}.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $comment_id The activity ID for the posted activity comment.
+ * @param array $params Parameters for the activity comment.
+ * @param object Parameters of the parent activity item (in this case, the blog post).
+ */
+function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) {
+	// if parent activity isn't a blog post, stop now!
+	if ( $parent_activity->type != 'new_blog_post' ) {
+		return;
+	}
+
+	// if activity comments are disabled for blog posts, stop now!
+	if ( bp_disable_blogforum_comments() ) {
+		return;
+	}
+
+	// get userdata
+	if ( $params['user_id'] == bp_loggedin_user_id() ) {
+		$user = buddypress()->loggedin_user->userdata;
+	} else {
+		$user = bp_core_get_core_userdata( $params['user_id'] );
+	}
+
+	// see if a parent WP comment ID exists
+	if ( ! empty( $params['parent_id'] ) ) {
+		$comment_parent = bp_activity_get_meta( $params['parent_id'], 'bp_blogs_post_comment_id' );
+	} else {
+		$comment_parent = 0;
+	}
+
+	// comment args
+	$args = array(
+		'comment_post_ID'      => $parent_activity->secondary_item_id,
+		'comment_author'       => bp_core_get_user_displayname( $params['user_id'] ),
+		'comment_author_email' => $user->user_email,
+		'comment_author_url'   => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
+		'comment_content'      => $params['content'],
+		'comment_type'         => '', // could be interesting to add 'buddypress' here...
+		'comment_parent'       => (int) $comment_parent,
+		'user_id'              => $params['user_id'],
+
+		// commenting these out for now
+		//'comment_author_IP'    => '127.0.0.1',
+		//'comment_agent'        => '',
+
+		'comment_approved'     => 1
+	);
+
+	// prevent separate activity entry being made
+	remove_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
+
+	// handle multisite
+	switch_to_blog( $parent_activity->item_id );
+
+	// handle timestamps for the WP comment after we've switched to the blog
+	$args['comment_date']     = current_time( 'mysql' );
+	$args['comment_date_gmt'] = current_time( 'mysql', 1 );
+
+	// post the comment
+	$post_comment_id = wp_insert_comment( $args );
+
+	// add meta to comment
+	add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id );
+
+	// add meta to activity comment
+	bp_activity_update_meta( $comment_id, 'bp_blogs_post_comment_id', $post_comment_id );
+
+	// resave activity comment with WP comment permalink
+	//
+	// in bp_blogs_activity_comment_permalink(), we change activity comment
+	// permalinks to use the post comment link
+	//
+	// @todo since this is done after AJAX posting, the activity comment permalink
+	//       doesn't change on the frontend until the next page refresh.
+	$resave_activity = new BP_Activity_Activity( $comment_id );
+	$resave_activity->primary_link = get_comment_link( $post_comment_id );
+	$resave_activity->save();
+
+	// multisite again!
+	restore_current_blog();
+
+	// add the comment hook back
+	add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
+
+	do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user );
+}
+add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 );
+
+/**
+ * Deletes the blog comment when the associated activity comment is deleted.
+ *
+ * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead
+ * of the 'bp_activity_delete_comment' action because we need to fetch the
+ * activity comment children before they are deleted.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param bool $retval
+ * @param int $parent_activity_id The parent activity ID for the activity comment.
+ * @param int $activity_id The activity ID for the pending deleted activity comment.
+ */
+function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id ) {
+	// check if parent activity is a blog post
+	$parent_activity = new BP_Activity_Activity( $parent_activity_id );
+	if ( 'new_blog_post' != $parent_activity->type ) {
+		return $retval;
+	}
+
+	// fetch the activity comments for the activity item
+	$activity = bp_activity_get( array(
+		'in'               => $activity_id,
+		'display_comments' => 'stream',
+	) );
+
+	// get all activity comment IDs for the pending deleted item
+	$activity_ids   = bp_activity_recurse_comments_activity_ids( $activity );
+	$activity_ids[] = $activity_id;
+
+	// handle multisite
+	// switch to the blog where the comment was made
+	switch_to_blog( $parent_activity->item_id );
+
+	// remove associated blog comments
+	bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) );
+
+	// multisite again!
+	restore_current_blog();
+
+	// rebuild activity comment tree
+	// emulate bp_activity_delete_comment()
+	BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
+
+	// we're overriding the default bp_activity_delete_comment() functionality
+	// so we need to return false
+	return false;
+}
+add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 3 );
+
+/**
+ * Updates the blog comment when the associated activity comment is edited.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param BP_Activity_Activity $activity The activity object.
+ */
+function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) {
+	// not an activity comment? stop now!
+	if ( 'activity_comment' !== $activity->type ) {
+		return;
+	}
+
+	// this is a new entry, so stop!
+	// we only want edits!
+	if ( empty( $activity->id ) ) {
+		return;
+	}
+
+	// prevent recursion
+	remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
+
+	// Try to see if a corresponding blog comment exists
+	$post_comment_id = bp_activity_get_meta( $activity->id, 'bp_blogs_post_comment_id' );
+
+	if ( empty( $post_comment_id ) ) {
+		return;
+	}
+
+	// fetch parent activity item
+	$parent_activity = new BP_Activity_Activity( $activity->item_id );
+
+	// sanity check
+	if ( 'new_blog_post' !== $parent_activity->type ) {
+		return;
+	}
+
+	// handle multisite
+	switch_to_blog( $parent_activity->item_id );
+
+	// update the blog post comment
+	wp_update_comment( array(
+		'comment_ID'      => $post_comment_id,
+		'comment_content' => $activity->content
+	) );
+
+	restore_current_blog();
+}
+add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
+
+/**
+ * When a post is trashed, remove each comment's associated activity meta.
+ *
+ * When a post is trashed and later untrashed, we currently don't reinstate
+ * activity items for these comments since their activity entries are already
+ * deleted when initially trashed.
+ *
+ * Since these activity entries are deleted, we need to remove the deleted
+ * activity comment IDs from each comment's meta when a post is trashed.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $post_id The post ID
+ * @param array $statuses Array of comment statuses. The key is comment ID, the
+ *        value is the $comment->comment_approved value.
+ */
+function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id, $statuses ) {
+	foreach ( $statuses as $comment_id => $comment_approved ) {
+		delete_comment_meta( $comment_id, 'bp_activity_comment_id' );
+	}
+}
+add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 );
+
+/**
+ * Utility function to set up some variables for use in the activity loop.
+ *
+ * Grabs the blog's comment depth and the post's open comment status options
+ * for later use in the activity and activity comment loops.
+ *
+ * This is to prevent having to requery these items later on.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @see bp_blogs_disable_activity_commenting()
+ * @see bp_blogs_setup_comment_loop_globals_on_ajax()
+ *
+ * @param object $activity The BP_Activity_Activity object
+ */
+function bp_blogs_setup_activity_loop_globals( $activity ) {
+	if ( ! is_object( $activity ) ) {
+		return;
+	}
+
+	// parent not a blog post? stop now!
+	if ( 'new_blog_post' !== $activity->type ) {
+		return;
+	}
+
+	if ( empty( $activity->id ) ) {
+		return;
+	}
+
+	// if we've already done this before, stop now!
+	if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) {
+		return;
+	}
+
+	$allow_comments = bp_blogs_comments_open( $activity );
+	$thread_depth   = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' );
+
+	// initialize a local object so we won't have to query this again in the
+	// comment loop
+	if ( empty( buddypress()->blogs->allow_comments ) ) {
+		buddypress()->blogs->allow_comments = array();
+	}
+	if ( empty( buddypress()->blogs->thread_depth ) ) {
+		buddypress()->blogs->thread_depth   = array();
+	}
+
+	// cache comment settings in the buddypress() singleton to reference later in
+	// the activity comment loop
+	// @see bp_blogs_disable_activity_replies()
+	//
+	// thread_depth is keyed by activity ID instead of blog ID because when we're
+	// in a comment loop, we don't have access to the blog ID...
+	// should probably object cache these values instead...
+	buddypress()->blogs->allow_comments[ $activity->id ] = $allow_comments;
+	buddypress()->blogs->thread_depth[ $activity->id ]   = $thread_depth;
+}
+
+/**
+ * Set up some globals used in the activity comment loop when AJAX is used.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @see bp_blogs_setup_activity_loop_globals()
+ */
+function bp_blogs_setup_comment_loop_globals_on_ajax() {
+	// not AJAX? stop now!
+	if ( ! defined( 'DOING_AJAX' ) ) {
+		return;
+	}
+	if ( false === (bool) constant( 'DOING_AJAX' ) ) {
+		return;
+	}
+
+	// get the parent activity item
+	$comment         = bp_activity_current_comment();
+	$parent_activity = new BP_Activity_Activity( $comment->item_id );
+
+	// setup the globals
+	bp_blogs_setup_activity_loop_globals( $parent_activity );
+}
+add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' );
+
+/**
+ * Disable activity commenting for blog posts based on certain criteria.
+ *
+ * If activity commenting is enabled for blog posts, we still need to disable
+ * commenting if:
+ *  - comments are disabled for the WP blog post from the admin dashboard
+ *  - the WP blog post is supposed to be automatically closed from comments
+ *    based on a certain age
+ *  - the activity entry is a 'new_blog_comment' type
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param bool $retval Is activity commenting enabled for this activity entry?
+ * @return bool
+ */
+function bp_blogs_disable_activity_commenting( $retval ) {
+	// if activity commenting is disabled, return current value
+	if ( bp_disable_blogforum_comments() ) {
+		return $retval;
+	}
+
+	// activity commenting is enabled for blog posts
+	switch ( bp_get_activity_action_name() ) {
+
+		// we still have to disable activity commenting for 'new_blog_comment' items
+		// commenting should only be done on the parent 'new_blog_post' item
+		case 'new_blog_comment' :
+			$retval = false;
+
+			break;
+
+		// check if commenting is disabled for the WP blog post
+		// we should extrapolate this and automate this for plugins... or not
+		case 'new_blog_post' :
+			global $activities_template;
+
+			// setup some globals we'll need to reference later
+			bp_blogs_setup_activity_loop_globals( $activities_template->activity );
+
+			// if comments are closed for the WP blog post, we should disable
+			// activity comments for this activity entry
+			if ( empty( buddypress()->blogs->allow_comments[bp_get_activity_id()] ) ) {
+				$retval = false;
+			}
+
+			break;
+	}
+
+	return $retval;
+}
+add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' );
+
+/**
+ * Check if an activity comment associated with a blog post can be replied to.
+ *
+ * By default, disables replying to activity comments if the corresponding WP
+ * blog post no longer accepts comments.
+ *
+ * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()}
+ * via {@link bp_blogs_setup_activity_loop_globals()}.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param bool $retval Are replies allowed for this activity reply?
+ * @param object $comment The activity comment object
+ * @return bool
+ */
+function bp_blogs_can_comment_reply( $retval, $comment ) {
+	if ( is_array( $comment ) ) {
+		$comment = (object) $comment;
+	}
+
+	// check comment depth and disable if depth is too large
+	if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
+		if ( $comment->mptt_left > buddypress()->blogs->thread_depth[$comment->item_id] ) {
+			$retval = false;
+		}
+	}
+
+	// check if we should disable activity replies based on the parent activity
+	if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ){
+		// the blog post has closed off commenting, so we should disable all activity
+		// comments under the parent 'new_blog_post' activity entry
+		if ( empty( buddypress()->blogs->allow_comments[$comment->item_id] ) ) {
+			$retval = false;
+		}
+	}
+
+	return $retval;
+}
+add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 );
+
+/**
+ * Changes activity comment permalinks to use the blog comment permalink
+ * instead of the activity permalink.
+ *
+ * This is only done if activity commenting is allowed and whether the parent
+ * activity item is a 'new_blog_post' entry.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $retval The activity comment permalink
+ * @return string
+ */
+function bp_blogs_activity_comment_permalink( $retval ) {
+	global $activities_template;
+
+	if ( isset( buddypress()->blogs->allow_comments[$activities_template->activity->current_comment->item_id] ) ){
+		$retval = $activities_template->activity->current_comment->primary_link;
+	}
+
+	return $retval;
+}
+add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' );
Index: bp-blogs/bp-blogs-functions.php
===================================================================
--- bp-blogs/bp-blogs-functions.php
+++ bp-blogs/bp-blogs-functions.php
@@ -182,12 +182,24 @@
 	if ( !bp_blogs_is_blog_recordable( $blog_id, $user_id ) )
 		return false;
 
-	$url         = get_home_url( $blog_id );
-	$name        = get_blog_option( $blog_id, 'blogname' );
-	$description = get_blog_option( $blog_id, 'blogdescription' );
+	$name = get_blog_option( $blog_id, 'blogname' );
 
-	if ( empty( $name ) )
+	if ( empty( $name ) ) {
 		return false;
+	}
+
+	$url             = get_home_url( $blog_id );
+	$description     = get_blog_option( $blog_id, 'blogdescription' );
+	$close_old_posts = get_blog_option( $blog_id, 'close_comments_for_old_posts' );
+	$close_days_old  = get_blog_option( $blog_id, 'close_comments_days_old' );
+
+	$thread_depth = get_blog_option( $blog_id, 'thread_comments' );
+	if ( ! empty( $thread_depth ) ) {
+		$thread_depth = get_blog_option( $blog_id, 'thread_comments_depth' );
+	} else {
+		// perhaps filter this?
+		$thread_depth = 1;
+	}
 
 	$recorded_blog          = new BP_Blogs_Blog;
 	$recorded_blog->user_id = $user_id;
@@ -199,6 +211,9 @@
 	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
 	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'description', $description );
 	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'last_activity', bp_core_current_time() );
+	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'close_comments_for_old_posts', $close_old_posts );
+	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'close_comments_days_old', $close_days_old );
+	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'thread_comments_depth', $thread_depth );
 
 	$is_private = !empty( $_POST['blog_public'] ) && (int) $_POST['blog_public'] ? false : true;
 	$is_private = !apply_filters( 'bp_is_new_blog_public', !$is_private );
@@ -252,6 +267,88 @@
 add_action( 'update_option_blogdescription', 'bp_blogs_update_option_blogdescription', 10, 2 );
 
 /**
+ * Update "Close comments for old posts" option in BuddyPress blogmeta table.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global object $wpdb DB Layer.
+ *
+ * @param string $oldvalue Value before save. Passed by do_action() but
+ *        unused here.
+ * @param string $newvalue Value to change meta to.
+ */
+function bp_blogs_update_option_close_comments_for_old_posts( $oldvalue, $newvalue ) {
+	global $wpdb;
+
+	bp_blogs_update_blogmeta( $wpdb->blogid, 'close_comments_for_old_posts', $newvalue );
+}
+add_action( 'update_option_close_comments_for_old_posts', 'bp_blogs_update_option_close_comments_for_old_posts', 10, 2 );
+
+/**
+ * Update "Close comments after days old" option in BuddyPress blogmeta table.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global object $wpdb DB Layer.
+ *
+ * @param string $oldvalue Value before save. Passed by do_action() but
+ *        unused here.
+ * @param string $newvalue Value to change meta to.
+ */
+function bp_blogs_update_option_close_close_comments_days_old( $oldvalue, $newvalue ) {
+	global $wpdb;
+
+	bp_blogs_update_blogmeta( $wpdb->blogid, 'close_comments_days_old', $newvalue );
+}
+add_action( 'update_option_close_comments_days_old', 'bp_blogs_update_option_close_comments_days_old', 10, 2 );
+
+/**
+ * When toggling threaded comments, update thread depth in blogmeta table.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global object $wpdb DB Layer.
+ *
+ * @param string $oldvalue Value before save. Passed by do_action() but
+ *        unused here.
+ * @param string $newvalue Value to change meta to.
+ */
+function bp_blogs_update_option_thread_comments( $oldvalue, $newvalue ) {
+	global $wpdb;
+
+	if ( empty( $newvalue ) ) {
+		$thread_depth = 1;
+	} else {
+		$thread_depth = get_option( 'thread_comments_depth' );
+	}
+
+	bp_blogs_update_blogmeta( $wpdb->blogid, 'thread_comments_depth', $thread_depth );
+}
+add_action( 'update_option_thread_comments', 'bp_blogs_update_option_thread_comments', 10, 2 );
+
+/**
+ * When updating comment depth, update thread depth in blogmeta table.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global object $wpdb DB Layer.
+ *
+ * @param string $oldvalue Value before save. Passed by do_action() but
+ *        unused here.
+ * @param string $newvalue Value to change meta to.
+ */
+function bp_blogs_update_option_thread_comments_depth( $oldvalue, $newvalue ) {
+	global $wpdb;
+
+	$comments_enabled = get_option( 'thread_comments' );
+
+	if (  $comments_enabled ) {
+		bp_blogs_update_blogmeta( $wpdb->blogid, 'thread_comments_depth', $newvalue );
+	}
+}
+add_action( 'update_option_thread_comments_depth', 'bp_blogs_update_option_thread_comments_depth', 10, 2 );
+
+/**
  * Detect a change in post status, and initiate an activity update if necessary.
  *
  * Posts get new activity updates when (a) they are being published, and (b)
@@ -262,24 +359,40 @@
  *
  * @since BuddyPress (2.0.0)
  *
+ * @todo Support untrashing better
+ *
  * @param string $new_status New status for the post.
  * @param string $old_status Old status for the post.
  * @param object $post Post data.
  */
 function bp_blogs_catch_transition_post_status( $new_status, $old_status, $post ) {
 
-	// Do nothing for edits
+	// This is an edit
 	if ( $new_status === $old_status ) {
-		return;
+		if ( $new_status == 'publish' ) {
+			bp_blogs_update_post( $post );
+		}
 	}
 
 	// Publishing a previously unpublished post
 	if ( 'publish' === $new_status ) {
-		return bp_blogs_record_post( $post->ID, $post );
+		// Untrashing the post
+		// Nothing here yet
+		if ( 'trash' == $old_status ) {}
+
+		// Record the post
+		bp_blogs_record_post( $post->ID, $post );
 
 	// Unpublishing a previously published post
 	} else if ( 'publish' === $old_status ) {
-		return bp_blogs_remove_post( $post->ID );
+		// Some form of pending status
+		// Only remove the activity entry
+		bp_blogs_delete_activity( array(
+			'item_id'           => get_current_blog_id(),
+			'secondary_item_id' => $post->ID,
+			'component'         => buddypress()->blogs->id,
+			'type'              => 'new_blog_post'
+		) );
 	}
 }
 add_action( 'transition_post_status', 'bp_blogs_catch_transition_post_status', 10, 3 );
@@ -369,14 +482,51 @@
 
 		// Update the blogs last activity
 		bp_blogs_update_blogmeta( $blog_id, 'last_activity', bp_core_current_time() );
-	} else {
-		bp_blogs_remove_post( $post_id, $blog_id, $user_id );
 	}
 
 	do_action( 'bp_blogs_new_blog_post', $post_id, $post, $user_id );
 }
 
 /**
+ * Updates a blog post's corresponding activity entry during a post edit.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @see bp_blogs_catch_transition_post_status()
+ *
+ * @param WP_Post $post
+ */
+function bp_blogs_update_post( $post ) {
+	if ( ! bp_is_active( 'activity' ) ) {
+		return;
+	}
+
+	$activity_id = bp_activity_get_activity_id( array(
+		'component'         => buddypress()->blogs->id,
+		'item_id'           => get_current_blog_id(),
+		'secondary_item_id' => $post->ID,
+		'type'              => 'new_blog_post',
+	 ) );
+
+	// activity ID doesn't exist, so stop!
+	if ( empty( $activity_id ) ) {
+		return;
+	}
+
+	// update the activity entry
+	$activity = new BP_Activity_Activity( $activity_id );
+	$activity->content = $post->post_content;
+	$activity->save();
+
+	// add post comment status to activity meta if closed
+	if( 'closed' == $post->comment_status ) {
+		bp_activity_update_meta( $activity_id, 'post_comment_status', $post->comment_status );
+	} else {
+		bp_activity_delete_meta( $activity_id, 'post_comment_status' );
+	}
+}
+
+/**
  * Record a new blog comment in the BuddyPress activity stream.
  *
  * Only posts the item if blog is public and post is not password-protected.
@@ -441,24 +591,96 @@
 		$post_permalink = get_permalink( $recorded_comment->comment_post_ID );
 		$comment_link   = get_comment_link( $recorded_comment->comment_ID );
 
-		// Prepare to record in activity streams
-		if ( is_multisite() )
-			$activity_action = sprintf( __( '%1$s commented on the post, %2$s, on the site %3$s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $recorded_comment->post->post_title ) . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
-		else
-			$activity_action = sprintf( __( '%1$s commented on the post, %2$s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $recorded_comment->post->post_title ) . '</a>' );
+		// Setup activity args
+		$args = array();
+
+		$args['user_id']       = $user_id;
+		$args['content']       = apply_filters_ref_array( 'bp_blogs_activity_new_comment_content', array( $recorded_comment->comment_content, &$recorded_comment, $comment_link ) );
+		$args['primary_link']  = apply_filters_ref_array( 'bp_blogs_activity_new_comment_primary_link', array( $comment_link,     &$recorded_comment ) );
+		$args['recorded_time'] = $recorded_comment->comment_date_gmt;
+
+		// Setup some different activity args depending if activity commenting is
+		// enabled or not
+
+		// if cannot comment, record separate activity entry
+		// this is the old way of doing things
+		if ( bp_disable_blogforum_comments() ) {
+			$args['type']              = 'new_blog_comment';
+			$args['item_id']           = $blog_id;
+			$args['secondary_item_id'] = $comment_id;
+
+			// record the activity entry
+			bp_blogs_record_activity( $args );
+
+		// record comment as BP activity comment under the parent 'new_blog_post'
+		// activity item
+		} else {
+			// this is a comment edit
+			// check to see if corresponding activity entry already exists
+			if ( ! empty( $_REQUEST['action'] ) ) {
+				$existing_activity_id = get_comment_meta( $comment_id, 'bp_activity_comment_id', true );
+
+				if ( ! empty( $existing_activity_id ) ) {
+					$args['id'] = $existing_activity_id;
+				}
+			}
 
-		$activity_content	= $recorded_comment->comment_content;
+			// find the parent 'new_blog_post' activity entry
+			$parent_activity_id = bp_activity_get_activity_id( array(
+				'user_id'           => $user_id,
+				'component'         => 'blogs',
+				'type'              => 'new_blog_post',
+				'item_id'           => $blog_id,
+				'secondary_item_id' => $recorded_comment->comment_post_ID
+			) );
+
+			// we found the parent activity entry
+			// so let's go ahead and reconfigure some activity args
+			if ( ! empty( $parent_activity_id ) ) {
+				// set the 'item_id' with the parent activity entry ID
+				$args['item_id'] = $parent_activity_id;
+
+				// now see if the WP parent comment has a BP activity ID
+				$comment_parent = 0;
+				if ( ! empty( $recorded_comment->comment_parent ) ) {
+					$comment_parent = get_comment_meta( $recorded_comment->comment_parent, 'bp_activity_comment_id', true );
+				}
 
-		// Record in activity streams
-		bp_blogs_record_activity( array(
-			'user_id'           => $user_id,
-			'content'           => apply_filters_ref_array( 'bp_blogs_activity_new_comment_content',      array( $activity_content, &$recorded_comment, $comment_link ) ),
-			'primary_link'      => apply_filters_ref_array( 'bp_blogs_activity_new_comment_primary_link', array( $comment_link,     &$recorded_comment                ) ),
-			'type'              => 'new_blog_comment',
-			'item_id'           => $blog_id,
-			'secondary_item_id' => $comment_id,
-			'recorded_time'     => $recorded_comment->comment_date_gmt
-		) );
+				// WP parent comment does not have a BP activity ID
+				// so set to 'new_blog_post' activity ID
+				if ( empty( $comment_parent ) ) {
+					$comment_parent = $parent_activity_id;
+				}
+
+				$args['secondary_item_id'] = $comment_parent;
+				$args['component']         = 'activity';
+				$args['type']              = 'activity_comment';
+
+			// could not find corresponding parent activity entry
+			// so wipe out $args array
+			} else {
+				$args = array();
+			}
+
+			// Record in activity streams
+			if ( ! empty( $args ) ) {
+				// @todo should we use bp_activity_new_comment()? that function will also send
+				// an email to people in the activity comment thread
+				//
+				// what if a site already has some comment email notification plugin setup?
+				// this is why I decided to go with bp_activity_add() to avoid any conflict
+				// with existing comment email notification plugins
+				$comment_activity_id = bp_activity_add( $args );
+
+				if ( empty( $args['id'] ) ) {
+					// add meta to activity comment
+					bp_activity_update_meta( $comment_activity_id, 'bp_blogs_post_comment_id', $comment_id );
+
+					// add meta to comment
+					add_comment_meta( $comment_id, 'bp_activity_comment_id', $comment_activity_id );
+				}
+			}
+		}
 
 		// Update the blogs last active date
 		bp_blogs_update_blogmeta( $blog_id, 'last_activity', bp_core_current_time() );
@@ -632,14 +854,99 @@
 function bp_blogs_remove_comment( $comment_id ) {
 	global $wpdb;
 
-	// Delete activity stream item
-	bp_blogs_delete_activity( array( 'item_id' => $wpdb->blogid, 'secondary_item_id' => $comment_id, 'type' => 'new_blog_comment' ) );
+	// activity comments are disabled for blog posts
+	// which means that individual activity items exist for blog comments
+	if ( bp_disable_blogforum_comments() ) {
+		// Delete the individual activity stream item
+		bp_blogs_delete_activity( array(
+			'item_id'           => $wpdb->blogid,
+			'secondary_item_id' => $comment_id,
+			'type'              => 'new_blog_comment'
+		) );
+
+	// activity comments are enabled for blog posts
+	// remove the associated activity item
+	} else {
+		// get associated activity ID from comment meta
+		$activity_id = get_comment_meta( $comment_id, 'bp_activity_comment_id', true );
+
+		// delete the associated activity comment
+		//
+		// also removes child post comments and associated activity comments
+		if ( ! empty( $activity_id ) && bp_is_active( 'activity' ) ) {
+			// fetch the activity comments for the activity item
+			$activity = bp_activity_get( array(
+				'in'               => $activity_id,
+				'display_comments' => 'stream',
+			) );
+
+			// get all activity comment IDs for the pending deleted item
+			if ( ! empty( $activity['activities'] ) ) {
+				$activity_ids   = bp_activity_recurse_comments_activity_ids( $activity );
+				$activity_ids[] = $activity_id;
+
+				// delete activity items
+				foreach ( $activity_ids as $activity_id ) {
+					bp_activity_delete( array(
+						'id' => $activity_id
+					) );
+				}
+
+				// remove associated blog comments
+				bp_blogs_remove_associated_blog_comments( $activity_ids );
+
+				// rebuild activity comment tree
+				BP_Activity_Activity::rebuild_activity_comment_tree( $activity['activities'][0]->item_id );
+			}
+		}
+	}
 
 	do_action( 'bp_blogs_remove_comment', $wpdb->blogid, $comment_id, bp_loggedin_user_id() );
 }
 add_action( 'delete_comment', 'bp_blogs_remove_comment' );
 
 /**
+ * Removes blog comments that are associated with activity comments.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @see bp_blogs_remove_comment()
+ * @see bp_blogs_sync_delete_from_activity_comment()
+ *
+ * @param array $activity_ids The activity IDs to check association with blog
+ *              comments.
+ * @param bool $force_delete Whether to force delete the comments. If false,
+ *             comments are trashed instead.
+ */
+function bp_blogs_remove_associated_blog_comments( $activity_ids = array(), $force_delete = true ) {
+	// query args
+	$query_args = array(
+		'meta_query' => array(
+			array(
+				'key'     => 'bp_activity_comment_id',
+				'value'   => implode( ',', (array) $activity_ids ),
+				'compare' => 'IN',
+			)
+		)
+	);
+
+	// get comment
+	$comment_query = new WP_Comment_Query;
+	$comments = $comment_query->query( $query_args );
+
+	// found the corresponding comments
+	// let's delete them!
+	foreach ( $comments as $comment ) {
+		wp_delete_comment( $comment->comment_ID, $force_delete );
+
+		// if we're trashing the comment, remove the meta key as well
+		if ( empty( $force_delete ) ) {
+			delete_comment_meta( $comment->comment_ID, 'bp_activity_comment_id' );
+		}
+	}
+}
+
+/**
  * When a blog comment status transition occurs, update the relevant activity's status.
  *
  * @since BuddyPress (1.6.0)
@@ -667,24 +974,29 @@
 	 */
 
 	// This clause was moved in from bp_blogs_remove_comment() in BuddyPress 1.6. It handles delete/hold.
-	if ( in_array( $new_status, array( 'delete', 'hold' ) ) )
+	if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) {
 		return bp_blogs_remove_comment( $comment->comment_ID );
 
 	// These clauses handle trash, spam, and un-spams.
-	elseif ( in_array( $new_status, array( 'trash', 'spam' ) ) )
+	} elseif ( in_array( $new_status, array( 'trash', 'spam' ) ) ) {
 		$action = 'spam_activity';
-	elseif ( 'approved' == $new_status )
+	} elseif ( 'approved' == $new_status ) {
 		$action = 'ham_activity';
+	}
 
 	// Get the activity
-	$activity_id = bp_activity_get_activity_id( array( 'component' => $bp->blogs->id, 'item_id' => get_current_blog_id(), 'secondary_item_id' => $comment->comment_ID, 'type' => 'new_blog_comment', ) );
+	if ( bp_disable_blogforum_comments() ) {
+		$activity_id = bp_activity_get_activity_id( array( 'component' => $bp->blogs->id, 'item_id' => get_current_blog_id(), 'secondary_item_id' => $comment->comment_ID, 'type' => 'new_blog_comment', ) );
+	} else {
+		$activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
+	}
 
 	// Check activity item exists
-	if ( ! $activity_id ) {
-
+	if ( empty( $activity_id ) ) {
 		// If no activity exists, but the comment has been approved, record it into the activity table.
-		if ( 'approved' == $new_status )
+		if ( 'approved' == $new_status ) {
 			return bp_blogs_record_comment( $comment->comment_ID, true );
+		}
 
 		return;
 	}
Index: bp-core/bp-core-options.php
===================================================================
--- bp-core/bp-core-options.php
+++ bp-core/bp-core-options.php
@@ -226,7 +226,14 @@
  * @return mixed The value for the option.
  */
 function bp_get_option( $option_name, $default = '' ) {
-	$value = get_blog_option( bp_get_root_blog_id(), $option_name, $default );
+	// check buddypress()->site_options array first
+	if ( isset( buddypress()->site_options[$option_name] ) ) {
+		$value = buddypress()->site_options[$option_name];
+
+	// query for the option if not available
+	} else {
+		$value = get_blog_option( bp_get_root_blog_id(), $option_name, $default );
+	}
 
 	return apply_filters( 'bp_get_option', $value );
 }
