Index: bp-activity/bp-activity-filters.php
===================================================================
--- bp-activity/bp-activity-filters.php
+++ bp-activity/bp-activity-filters.php
@@ -89,7 +89,7 @@ add_filter( 'bp_get_activity_feed_item_description', 'bp_activity_make_nofollow_
 add_filter( 'pre_comment_content',                   'bp_activity_at_name_filter' );
 add_filter( 'group_forum_topic_text_before_save',    'bp_activity_at_name_filter' );
 add_filter( 'group_forum_post_text_before_save',     'bp_activity_at_name_filter' );
-add_filter( 'the_content', 			     'bp_activity_at_name_filter' );
+add_filter( 'the_content',                           'bp_activity_at_name_filter' );
 
 add_filter( 'bp_get_activity_parent_content',        'bp_create_excerpt' );
 
@@ -99,7 +99,7 @@ add_filter( 'bp_get_activity_content',      'bp_activity_truncate_entry', 5 );
 /** Actions *******************************************************************/
 
 // At-name filter
-add_action( 'bp_activity_after_save', 'bp_activity_at_name_filter_updates' );
+add_action( 'bp_activity_before_save', 'bp_activity_at_name_filter_updates' );
 
 // Activity stream moderation
 add_action( 'bp_activity_before_save', 'bp_activity_check_moderation_keys', 2, 1 );
@@ -194,76 +194,99 @@ function bp_activity_filter_kses( $content ) {
 }
 
 /**
- * Finds and links @-mentioned users in the contents of activity items
+ * Finds and links @-mentioned users in the contents of a given item.
  *
  * @since BuddyPress (1.2)
  *
- * @param string $content The activity content
- * @param int $activity_id The activity id
+ * @param string $content The contents of a given item.
+ * @param int $activity_id The activity id. Deprecated.
  *
  * @uses bp_activity_find_mentions()
- * @uses bp_is_username_compatibility_mode()
- * @uses bp_core_get_userid_from_nicename()
- * @uses bp_activity_at_message_notification()
  * @uses bp_core_get_user_domain()
- * @uses bp_activity_adjust_mention_count()
  *
  * @return string $content Content filtered for mentions
  */
 function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
-	if ( $activity_id & bp_is_active( 'activity' ) ) {
-		$activity = new BP_Activity_Activity( $activity_id );
-
-		// If this activity has been marked as spam, don't do anything. This prevents @notifications being sent.
-		if ( !empty( $activity ) && $activity->is_spam )
-			return $content;
-	}
 
+	// Try to find mentions
 	$usernames = bp_activity_find_mentions( $content );
-	foreach( (array) $usernames as $username ) {
-		if ( bp_is_username_compatibility_mode() )
-			$user_id = username_exists( $username );
-		else
-			$user_id = bp_core_get_userid_from_nicename( $username );
-
-		if ( empty( $user_id ) )
-			continue;
-
-		// If an activity_id is provided, we can send email and BP notifications
-		if ( $activity_id && apply_filters( 'bp_activity_at_name_do_notifications', true ) ) {
-			bp_activity_at_message_notification( $activity_id, $user_id );
-		}
 
+	// No mentions? Stop now!
+	if ( empty( $usernames ) )
+		return $content;
+
+	// Linkify the mentions with the username
+	foreach( (array) $usernames as $user_id => $username ) {
 		$content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
 	}
 
-	// Adjust the activity count for this item
-	if ( $activity_id )
-		bp_activity_adjust_mention_count( $activity_id, 'add' );
-
+	// Return the content
 	return $content;
 }
 
 /**
- * Catch mentions in saved activity items
+ * Catch mentions in activity items before they are saved into the database.
+ *
+ * If mentions are found, replace @mention text with user links and add our
+ * hook to send mentions after the activity item is saved.
  *
  * @since BuddyPress (1.5)
  *
  * @param obj $activity
  *
- * @uses remove_filter() To remove the 'bp_activity_at_name_filter_updates' hook.
  * @uses bp_activity_at_name_filter()
  * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
  */
 function bp_activity_at_name_filter_updates( $activity ) {
-	// Only run this function once for a given activity item
-	remove_filter( 'bp_activity_after_save', 'bp_activity_at_name_filter_updates' );
+	// If activity was marked as spam, stop the rest of this function.
+	if ( ! empty( $activity->is_spam ) )
+		return;
 
-	// Run the content through the linking filter, making sure to increment mention count
-	$activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
+	// Try to find mentions
+	$usernames = bp_activity_find_mentions( $activity->content );
+
+	// We have mentions!
+	if ( ! empty( $usernames ) ) {
+		// Replace @mention text with userlinks
+		foreach( (array) $usernames as $user_id => $username ) {
+			$activity->content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $activity->content );
+		}
+
+		// Add our hook to send @mention emails after the activity item is saved
+		add_action( 'bp_activity_after_save', 'bp_activity_at_name_send_emails' );
+	}
+}
 
-	// Resave the activity with the new content
-	$activity->save();
+/**
+ * Sends emails and BP notifications for @-mentioned users in the contents of
+ * an activity item.
+ *
+ * @since BuddyPress (1.7)
+ *
+ * @param obj $activity The BP_Activity_Activity_Object
+ *
+ * @uses bp_activity_find_mentions()
+ * @uses bp_activity_at_message_notification()
+ * @uses bp_activity_adjust_mention_count()
+ */
+function bp_activity_at_name_send_emails( $activity ) {
+	// Try to find mentions
+	$usernames = bp_activity_find_mentions( $activity->content );
+
+	// Still empty? Stop now!
+	if ( empty( $usernames ) )
+		return;
+
+	// Send @mentions and setup BP notifications
+	foreach( (array) $usernames as $user_id => $username ) {
+		// If you want to disable notifications, you can use this filter to stop email sending
+		if ( apply_filters( 'bp_activity_at_name_do_notifications', true, $usernames ) ) {
+			bp_activity_at_message_notification( $activity->id, $user_id );
+		}
+
+		// Updates mention count for the user
+		bp_activity_update_mention_count_for_user( $user_id, $activity->id );
+	}
 }
 
 /**
Index: bp-activity/bp-activity-functions.php
===================================================================
--- bp-activity/bp-activity-functions.php
+++ bp-activity/bp-activity-functions.php
@@ -32,9 +32,8 @@ function bp_activity_has_directory() {
  *
  * @since BuddyPress (1.5)
  *
- * @param string $content The content of the activity, usually found in $activity->content
- *
- * @return bool|array $usernames Array of the found usernames that match existing users. False if no matches
+ * @param string $content The content of the activity, usually found in $activity->content.
+ * @return mixed Associative array with user ID as key and username as value. Boolean false if no mentions found.
  */
 function bp_activity_find_mentions( $content ) {
 	$pattern = '/[@]+([A-Za-z0-9-_\.@]+)\b/';
@@ -44,7 +43,22 @@ function bp_activity_find_mentions( $content ) {
 	if ( !$usernames = array_unique( $usernames[1] ) )
 		return false;
 
-	return $usernames;
+	$mentioned_users = array();
+
+	foreach( (array) $usernames as $key => $username ) {
+		if ( bp_is_username_compatibility_mode() )
+			$user_id = username_exists( $username );
+		else
+			$user_id = bp_core_get_userid_from_nicename( $username );
+
+		if ( ! empty( $user_id ) )
+			$mentioned_users[$user_id] = $username;
+	}
+
+	if ( empty( $mentioned_users ) )
+		return false;
+
+	return $mentioned_users;
 }
 
 /**
@@ -68,55 +82,69 @@ function bp_activity_clear_new_mentions( $user_id ) {
  * @param int $activity_id The unique id for the activity item
  * @param string $action Can be 'delete' or 'add'. Defaults to 'add'
  *
- * @uses BP_Activity_Activity() {@link BP_Activity_Activity}
  * @uses bp_activity_find_mentions()
- * @uses bp_is_username_compatibility_mode()
- * @uses bp_core_get_userid_from_nicename()
+ * @uses bp_activity_update_mention_count_for_user()
+ */
+function bp_activity_adjust_mention_count( $activity_id, $action = 'add' ) {
+	// Try to find mentions
+	$usernames = bp_activity_find_mentions( strip_tags( $activity->content ) );
+
+	// Still empty? Stop now
+	if ( empty( $usernames ) )
+		return;
+
+	// Increment mention count foreach mentioned user
+	foreach( (array) $usernames as $user_id => $username ) {
+		bp_activity_update_mention_count_for_user( $user_id, $activity_id, $action );
+	}
+}
+
+/**
+ * Updates the mention count for the user in question.
+ *
+ * @since BuddyPress (1.7)
+ *
+ * @param int $user_id The user ID
+ * @param int $activity_id The unique id for the activity item
+ * @param string $action Can be 'delete' or 'add'. Defaults to 'add'
+ *
  * @uses bp_get_user_meta()
  * @uses bp_update_user_meta()
+ * @return bool
  */
-function bp_activity_adjust_mention_count( $activity_id, $action = 'add' ) {
-	$activity = new BP_Activity_Activity( $activity_id );
+function bp_activity_update_mention_count_for_user( $user_id, $activity_id, $action = 'add' ) {
+	if ( empty( $user_id ) || empty( $activity_id ) )
+		return false;
 
-	if ( $usernames = bp_activity_find_mentions( strip_tags( $activity->content ) ) ) {
-		foreach( (array) $usernames as $username ) {
-			if ( bp_is_username_compatibility_mode() )
-				$user_id = username_exists( $username );
-			else
-				$user_id = bp_core_get_userid_from_nicename( $username );
-
-			if ( empty( $user_id ) )
-				continue;
-
-			// Adjust the mention list and count for the member
-			$new_mention_count = (int)bp_get_user_meta( $user_id, 'bp_new_mention_count', true );
-			if ( !$new_mentions = bp_get_user_meta( $user_id, 'bp_new_mentions', true ) )
-				$new_mentions = array();
-
-			switch ( $action ) {
-				case 'delete' :
-					$key = array_search( $activity_id, $new_mentions );
-					if ( $key !== false ) {
-						unset( $new_mentions[$key] );
-					}
-					break;
-
-				case 'add' :
-				default :
-					if ( !in_array( $activity_id, $new_mentions ) ) {
-						$new_mentions[] = (int) $activity_id;
-					}
-					break;
-			}
+	// Adjust the mention list and count for the member
+	$new_mention_count = (int)bp_get_user_meta( $user_id, 'bp_new_mention_count', true );
+	if ( !$new_mentions = bp_get_user_meta( $user_id, 'bp_new_mentions', true ) )
+		$new_mentions = array();
 
-			// Get an updated mention count
-			$new_mention_count = count( $new_mentions );
+	switch ( $action ) {
+		case 'delete' :
+			$key = array_search( $activity_id, $new_mentions );
+			if ( $key !== false ) {
+				unset( $new_mentions[$key] );
+			}
+			break;
 
-			// Resave the user_meta
-			bp_update_user_meta( $user_id, 'bp_new_mention_count', $new_mention_count );
-			bp_update_user_meta( $user_id, 'bp_new_mentions', $new_mentions );
-		}
+		case 'add' :
+		default :
+			if ( !in_array( $activity_id, $new_mentions ) ) {
+				$new_mentions[] = (int) $activity_id;
+			}
+			break;
 	}
+
+	// Get an updated mention count
+	$new_mention_count = count( $new_mentions );
+
+	// Resave the user_meta
+	bp_update_user_meta( $user_id, 'bp_new_mention_count', $new_mention_count );
+	bp_update_user_meta( $user_id, 'bp_new_mentions', $new_mentions );
+
+	return true;
 }
 
 /**