diff --git bp-activity/bp-activity-classes.php bp-activity/bp-activity-classes.php
index a543cc3..582b794 100644
--- bp-activity/bp-activity-classes.php
+++ bp-activity/bp-activity-classes.php
@@ -361,6 +361,12 @@ class BP_Activity_Activity {
 			$where_conditions[] = "a.type != 'activity_comment'";
 		}
 
+		// Exclude 'last_activity' items unless the 'action' filter has
+		// been explicitly set
+		if ( empty( $filter['object'] ) ) {
+			$where_conditions[] = "a.type != 'last_activity'";
+		}
+
 		// Filter the where conditions
 		$where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql );
 
@@ -1034,13 +1040,15 @@ class BP_Activity_Activity {
 		global $wpdb;
 
 		// split items at the comma
-		$items_dirty = explode( ',', $items );
+		if ( ! is_array( $items ) ) {
+			$items = explode( ',', $items );
+		}
 
 		// array of prepared integers or quoted strings
 		$items_prepared = array();
 
 		// clean up and format each item
-		foreach ( $items_dirty as $item ) {
+		foreach ( $items as $item ) {
 			// clean up the string
 			$item = trim( $item );
 			// pass everything through prepare for security and to safely quote strings
@@ -1092,7 +1100,7 @@ class BP_Activity_Activity {
 
 		if ( !empty( $filter_array['action'] ) ) {
 			$action_sql = BP_Activity_Activity::get_in_operator_sql( 'a.type', $filter_array['action'] );
-			if ( !empty( $action_sql ) )
+			if ( ! empty( $action_sql ) )
 				$filter_sql[] = $action_sql;
 		}
 
diff --git bp-core/admin/bp-core-schema.php bp-core/admin/bp-core-schema.php
index 6001979..a082d87 100644
--- bp-core/admin/bp-core-schema.php
+++ bp-core/admin/bp-core-schema.php
@@ -23,14 +23,14 @@ function bp_core_install( $active_components = false ) {
 	if ( empty( $active_components ) )
 		$active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) );
 
+	// Activity Streams
+	// Install tables even when inactive, to store last_activity data
+	bp_core_install_activity_streams();
+
 	// Notifications
 	if ( !empty( $active_components['notifications'] ) )
 		bp_core_install_notifications();
 
-	// Activity Streams
-	if ( !empty( $active_components['activity'] ) )
-		bp_core_install_activity_streams();
-
 	// Friend Connections
 	if ( !empty( $active_components['friends'] ) )
 		bp_core_install_friends();
diff --git bp-core/bp-core-classes.php bp-core/bp-core-classes.php
index ff8744a..9b2cf5a 100644
--- bp-core/bp-core-classes.php
+++ bp-core/bp-core-classes.php
@@ -245,10 +245,10 @@ class BP_User_Query {
 			// number of minutes used as an interval
 			case 'online' :
 				$this->uid_name = 'user_id';
-				$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$wpdb->usermeta} u";
-				$sql['where'][] = $wpdb->prepare( "u.meta_key = %s", bp_get_user_meta_key( 'last_activity' ) );
-				$sql['where'][] = $wpdb->prepare( "u.meta_value >= DATE_SUB( UTC_TIMESTAMP(), INTERVAL %d MINUTE )", apply_filters( 'bp_user_query_online_interval', 15 ) );
-				$sql['orderby'] = "ORDER BY u.meta_value";
+				$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$bp->members->table_name_last_activity} u";
+				$sql['where'][] = $wpdb->prepare( "u.component = %s AND u.type = 'last_activity'", buddypress()->members->id );
+				$sql['where'][] = $wpdb->prepare( "u.date_recorded >= DATE_SUB( UTC_TIMESTAMP(), INTERVAL %d MINUTE )", apply_filters( 'bp_user_query_online_interval', 15 ) );
+				$sql['orderby'] = "ORDER BY u.date_recorded";
 				$sql['order']   = "DESC";
 
 				break;
@@ -259,8 +259,8 @@ class BP_User_Query {
 			case 'newest' :
 			case 'random' :
 				$this->uid_name = 'user_id';
-				$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$wpdb->usermeta} u";
-				$sql['where'][] = $wpdb->prepare( "u.meta_key = %s", bp_get_user_meta_key( 'last_activity' ) );
+				$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$bp->members->table_name_last_activity} u";
+				$sql['where'][] = $wpdb->prepare( "u.component = %s AND u.type = 'last_activity'", buddypress()->members->id );
 
 				if ( 'newest' == $type ) {
 					$sql['orderby'] = "ORDER BY u.user_id";
@@ -268,7 +268,7 @@ class BP_User_Query {
 				} else if ( 'random' == $type ) {
 					$sql['orderby'] = "ORDER BY rand()";
 				} else {
-					$sql['orderby'] = "ORDER BY u.meta_value";
+					$sql['orderby'] = "ORDER BY u.date_recorded";
 					$sql['order'] = "DESC";
 				}
 
@@ -540,6 +540,8 @@ class BP_User_Query {
 		// Turn user ID's into a query-usable, comma separated value
 		$user_ids_sql = implode( ',', wp_parse_id_list( $this->user_ids ) );
 
+		$bp = buddypress();
+
 		/**
 		 * Use this action to independently populate your own custom extras.
 		 *
@@ -555,13 +557,22 @@ class BP_User_Query {
 		 */
 		do_action_ref_array( 'bp_user_query_populate_extras', array( $this, $user_ids_sql ) );
 
+		// Fetch last_active data from the activity table
+		$last_activities = BP_Core_User::get_last_activity( $this->user_ids );
+
+		if ( ! empty( $last_activities ) ) {
+			foreach ( $last_activities as $la_user => $la_value ) {
+				if ( isset( $this->results[ $la_user ] ) ) {
+					$this->results[ $la_user ]->last_activity = $la_value['date_recorded'];
+				}
+			}
+		}
+
 		// Fetch usermeta data
 		// We want the three following pieces of info from usermeta:
 		// - friend count
-		// - last activity
 		// - latest update
 		$total_friend_count_key = bp_get_user_meta_key( 'total_friend_count' );
-		$last_activity_key      = bp_get_user_meta_key( 'last_activity'      );
 		$bp_latest_update_key   = bp_get_user_meta_key( 'bp_latest_update'   );
 
 		// total_friend_count must be set for each user, even if its
@@ -571,7 +582,7 @@ class BP_User_Query {
 		}
 
 		// Create, prepare, and run the seperate usermeta query
-		$user_metas = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, meta_key, meta_value FROM {$wpdb->usermeta} WHERE meta_key IN (%s,%s,%s) AND user_id IN ({$user_ids_sql})", $total_friend_count_key, $last_activity_key, $bp_latest_update_key ) );
+		$user_metas = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, meta_key, meta_value FROM {$wpdb->usermeta} WHERE meta_key IN (%s,%s) AND user_id IN ({$user_ids_sql})", $total_friend_count_key, $bp_latest_update_key ) );
 
 		// The $members_template global expects the index key to be different
 		// from the meta_key in some cases, so we rejig things here.
@@ -581,10 +592,6 @@ class BP_User_Query {
 					$key = 'total_friend_count';
 					break;
 
-				case $last_activity_key :
-					$key = 'last_activity';
-					break;
-
 				case $bp_latest_update_key :
 					$key = 'latest_update';
 					break;
@@ -1299,6 +1306,163 @@ class BP_Core_User {
 
 		return $user;
 	}
+
+	/**
+	 * Get last activity data for a user or set of users.
+	 *
+	 * @param int|array User IDs or multiple user IDs.
+	 * @return array
+	 */
+	public static function get_last_activity( $user_id ) {
+		global $wpdb;
+
+		if ( is_array( $user_id ) ) {
+			$user_ids = wp_parse_id_list( $user_id );
+		} else {
+			$user_ids = array( absint( $user_id ) );
+		}
+
+		if ( empty( $user_ids ) ) {
+			return false;
+		}
+
+		$bp = buddypress();
+
+		$user_ids_sql = implode( ',', $user_ids );
+		$user_count   = count( $user_ids );
+
+		$last_activities = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, date_recorded FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' AND user_id IN ({$user_ids_sql}) LIMIT {$user_count}", $bp->members->id ) );
+
+		// Re-key
+		$retval = array();
+		foreach ( $last_activities as $last_activity ) {
+			$retval[ $last_activity->user_id ] = array(
+				'user_id'       => $last_activity->user_id,
+				'date_recorded' => $last_activity->date_recorded,
+				'activity_id'   => $last_activity->id,
+			);
+		}
+
+		return $retval;
+	}
+
+	/**
+	 * Set a user's last_activity value.
+	 *
+	 * Will create a new entry if it does not exist. Otherwise updates the
+	 * existing entry.
+	 *
+	 * @since 2.0
+	 *
+	 * @param int $user_id ID of the user whose last_activity you are updating.
+	 * @param string $time MySQL-formatted time string.
+	 * @return bool True on success, false on failure.
+	 */
+	public static function update_last_activity( $user_id, $time ) {
+		global $wpdb;
+
+		$table_name = buddypress()->members->table_name_last_activity;
+
+		$existing = self::get_last_activity( $user_id );
+
+		if ( ! empty( $existing ) ) {
+			$data = array(
+				'date_recorded' => $time,
+			);
+
+			$data_format = array(
+				'%s',
+			);
+
+			$where = array(
+			);
+
+			$where_format = array(
+				'%d',
+			);
+
+			$updated = $wpdb->update(
+				$table_name,
+
+				// Data to update
+				array(
+					'date_recorded' => $time,
+				),
+
+				// WHERE
+				array(
+					'id' => $existing[ $user_id ]['activity_id'],
+				),
+
+				// Data sanitization format
+				array(
+					'%s',
+				),
+
+				// WHERE sanitization format
+				array(
+					'%d',
+				)
+			);
+		} else {
+			$updated = $wpdb->insert(
+				$table_name,
+
+				// Data
+				array(
+					'user_id'       => $user_id,
+					'component'     => buddypress()->members->id,
+					'type'          => 'last_activity',
+					'date_recorded' => $time,
+				),
+
+				// Data sanitization format
+				array(
+					'%d',
+					'%s',
+					'%s',
+					'%s',
+				)
+			);
+		}
+
+		return $updated;
+	}
+
+	/**
+	 * Delete a user's last_activity value.
+	 *
+	 * @since 2.0
+	 *
+	 * @param int $user_id
+	 * @return bool True on success, false on failure or if no last_activity
+	 *         is found for the user.
+	 */
+	public static function delete_last_activity( $user_id ) {
+		global $wpdb;
+
+		$existing = self::get_last_activity( $user_id );
+
+		if ( empty( $existing ) ) {
+			return false;
+		}
+
+		$deleted = $wpdb->delete(
+			buddypress()->members->table_name_last_activity,
+
+			// WHERE
+			array(
+				'id' => $existing[ $user_id ]['activity_id'],
+			),
+
+			// WHERE sanitization format
+			array(
+				'%s',
+			)
+		);
+
+		return $deleted;
+	}
 }
 
 
diff --git bp-core/bp-core-functions.php bp-core/bp-core-functions.php
index 0e95ce7..120875e 100644
--- bp-core/bp-core-functions.php
+++ bp-core/bp-core-functions.php
@@ -1038,10 +1038,10 @@ function bp_core_get_last_activity( $last_activity_date, $string ) {
  *
  * Plugin authors should use BP's _user_meta() functions, which bakes in
  * bp_get_user_meta_key():
- *    $last_active = bp_get_user_meta( $user_id, 'last_activity', true );
+ *    $friend_count = bp_get_user_meta( $user_id, 'total_friend_count', true );
  * If you must use WP's _user_meta() functions directly for some reason, you
  * should use this function to determine the $key parameter, eg
- *    $last_active = get_user_meta( $user_id, bp_get_user_meta_key( 'last_activity' ), true );
+ *    $friend_count = get_user_meta( $user_id, bp_get_user_meta_key( 'total_friend_count' ), true );
  * If using the WP functions, do not not hardcode your meta keys.
  *
  * @since BuddyPress (1.5.0)
diff --git bp-core/bp-core-update.php bp-core/bp-core-update.php
index dd353bb..c626979 100644
--- bp-core/bp-core-update.php
+++ bp-core/bp-core-update.php
@@ -225,6 +225,11 @@ function bp_version_updater() {
 		if ( $raw_db_version < 7553 ) {
 			bp_update_to_1_9();
 		}
+
+		// 2.0
+		if ( $raw_db_version < 7767 ) {
+			bp_update_to_2_0();
+		}
 	}
 
 	/** All done! *************************************************************/
@@ -301,6 +306,38 @@ function bp_update_to_1_9() {
 }
 
 /**
+ * 2.0 update routine.
+ *
+ * - Ensure that the activity tables are installed, for last_activity storage.
+ * - Migrate last_activity data from usermeta to activity table
+ */
+function bp_update_to_2_0() {
+	global $wpdb;
+
+	// Install activity tables
+	bp_core_install_activity_streams();
+
+	$bp = buddypress();
+
+	// Migrate data
+	// The "NOT IN" clause prevents duplicates
+	$sql = "INSERT INTO {$bp->members->table_name_last_activity} (`user_id`, `component`, `type`, `date_recorded` ) (
+		  SELECT user_id, '{$bp->members->id}' as component, 'last_activity' as type, meta_value AS date_recorded
+		  FROM {$wpdb->usermeta}
+		  WHERE
+		    meta_key = 'last_activity'
+		    AND
+		    user_id NOT IN (
+		      SELECT user_id
+		      FROM {$bp->members->table_name_last_activity}
+		      WHERE component = '{$bp->members->id}' AND type = 'last_activity'
+		    )
+	);";
+
+	$wpdb->query( $sql );
+}
+
+/**
  * Redirect user to BP's What's New page on first page load after activation.
  *
  * @since BuddyPress (1.7.0)
diff --git bp-friends/bp-friends-classes.php bp-friends/bp-friends-classes.php
index 0ea096e..cb4afac 100644
--- bp-friends/bp-friends-classes.php
+++ bp-friends/bp-friends-classes.php
@@ -364,9 +364,27 @@ class BP_Friends_Friendship {
 	public static function get_bulk_last_active( $user_ids ) {
 		global $wpdb;
 
-		$user_ids = implode( ',', wp_parse_id_list( $user_ids ) );
+		$last_activities = BP_Core_User::get_last_activity( $user_ids );
+
+		// Sort and structure as expected in legacy function
+		usort( $last_activities, create_function( '$a, $b', '
+			if ( $a["date_recorded"] == $b["date_recorded"] ) {
+				return 0;
+			}
+
+			return ( strtotime( $a["date_recorded"] ) < strtotime( $b["date_recorded"] ) ) ? 1 : -1;
+		' ) );
+
+		$retval = array();
+		foreach ( $last_activities as $last_activity ) {
+			$u = new stdClass;
+			$u->last_activity = $last_activity['date_recorded'];
+			$u->user_id       = $last_activity['user_id'];
+
+			$retval[] = $u;
+		}
 
-		return $wpdb->get_results( $wpdb->prepare( "SELECT meta_value as last_activity, user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND user_id IN ( {$user_ids} ) ORDER BY meta_value DESC", bp_get_user_meta_key( 'last_activity' ) ) );
+		return $retval;
 	}
 
 	/**
diff --git bp-loader.php bp-loader.php
index f17ebbb..0d3e1bb 100644
--- bp-loader.php
+++ bp-loader.php
@@ -304,7 +304,7 @@ class BuddyPress {
 		/** Versions **************************************************/
 
 		$this->version    = '2.0-alpha-7752';
-		$this->db_version = 7553;
+		$this->db_version = 7767;
 
 		/** Loading ***************************************************/
 
diff --git bp-members/bp-members-functions.php bp-members/bp-members-functions.php
index d7744fa..4994f74 100644
--- bp-members/bp-members-functions.php
+++ bp-members/bp-members-functions.php
@@ -510,6 +510,8 @@ function bp_core_get_active_member_count() {
 	global $wpdb;
 
 	if ( !$count = get_transient( 'bp_active_member_count' ) ) {
+		$bp = buddypress();
+
 		// Avoid a costly join by splitting the lookup
 		if ( is_multisite() ) {
 			$sql = "SELECT ID FROM {$wpdb->users} WHERE (user_status != 0 OR deleted != 0 OR user_status != 0)";
@@ -519,7 +521,7 @@ function bp_core_get_active_member_count() {
 
 		$exclude_users     = $wpdb->get_col( $sql );
 		$exclude_users_sql = !empty( $exclude_users ) ? "AND user_id NOT IN (" . implode( ',', wp_parse_id_list( $exclude_users ) ) . ")" : '';
-		$count             = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(user_id) FROM {$wpdb->usermeta} WHERE meta_key = %s {$exclude_users_sql}", bp_get_user_meta_key( 'last_activity' ) ) );
+		$count             = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(user_id) FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' {$exclude_users_sql}", $bp->members->id ) );
 
 		set_transient( 'bp_active_member_count', $count );
 	}
@@ -817,12 +819,13 @@ function bp_is_user_inactive( $user_id = 0 ) {
 }
 
 /**
- * Update a user's last activity
+ * Update a user's last activity.
+ *
+ * @since BuddyPress (1.9.0)
  *
- * @since BuddyPress (1.9)
- * @param int $user_id ID of the user being updated
- * @param string $time Time of last activity, in 'Y-m-d H:i:s' format
- * @return bool True on success
+ * @param int $user_id ID of the user being updated.
+ * @param string $time Time of last activity, in 'Y-m-d H:i:s' format.
+ * @return bool True on success, false on failure.
  */
 function bp_update_user_last_activity( $user_id = 0, $time = '' ) {
 	// Fall back on current user
@@ -840,23 +843,88 @@ function bp_update_user_last_activity( $user_id = 0, $time = '' ) {
 		$time = bp_core_current_time();
 	}
 
-	return bp_update_user_meta( $user_id, 'last_activity', $time );
+	// As of BuddyPress 2.0, last_activity is no longer stored in usermeta.
+	// However, we mirror it there for backward compatibility. Do not use!
+	// Remove our warning and re-add.
+	remove_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
+	update_user_meta( $user_id, 'last_activity', $time );
+	add_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
+
+	return BP_Core_User::update_last_activity( $user_id, $time );
 }
 
 /**
- * Get the last activity for a given user
+ * Backward compatibility for 'last_activity' usermeta fetching.
  *
- * @param int $user_id The ID of the user
+ * In BuddyPress 2.0, user last_activity data was moved out of usermeta. For
+ * backward compatibility, we continue to mirror the data there. This function
+ * serves two purposes: it warns plugin authors of the change, and it returns
+ * the data from the proper location.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @access private For internal use only.
+ *
+ * @param null $retval
+ * @param int $object_id ID of the user.
+ * @param string $meta_key Meta key being fetched.
+ */
+function _bp_get_user_meta_last_activity_warning( $retval, $object_id, $meta_key ) {
+	static $warned;
+
+	if ( 'last_activity' === $meta_key ) {
+		// Don't send the warning more than once per pageload
+		if ( empty( $warned ) ) {
+			_doing_it_wrong( 'get_user_meta( $user_id, \'last_activity\' )', __( 'User last_activity data is no longer stored in usermeta. Use bp_get_user_last_activity() instead.', 'buddypress' ), '2.0.0' );
+			$warned = 1;
+		}
+
+		return bp_get_user_last_activity( $object_id );
+	}
+
+	return $retval;
+}
+add_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
+
+/**
+ * Backward compatibility for 'last_activity' usermeta setting.
+ *
+ * In BuddyPress 2.0, user last_activity data was moved out of usermeta. For
+ * backward compatibility, we continue to mirror the data there. This function
+ * serves two purposes: it warns plugin authors of the change, and it updates
+ * the data in the proper location.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @access private For internal use only.
+ *
+ * @param int $meta_id ID of the just-set usermeta row.
+ * @param int $object_id ID of the user.
+ * @param string $meta_key Meta key being fetched.
+ * @param string $meta_value Active time.
+ */
+function _bp_update_user_meta_last_activity_warning( $meta_id, $object_id, $meta_key, $meta_value ) {
+	if ( 'last_activity' === $meta_key ) {
+		_doing_it_wrong( 'update_user_meta( $user_id, \'last_activity\' )', __( 'User last_activity data is no longer stored in usermeta. Use bp_update_user_last_activity() instead.', 'buddypress' ), '2.0.0' );
+		bp_update_user_last_activity( $object_id, $meta_value );
+	}
+}
+add_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
+
+/**
+ * Get the last activity for a given user.
+ *
+ * @param int $user_id The ID of the user.
  * @return string Time of last activity, in 'Y-m-d H:i:s' format, or an empty
- *   string if none is found
+ *         string if none is found.
  */
 function bp_get_user_last_activity( $user_id = 0 ) {
-	// Fall back on current user
-	if ( empty( $user_id ) ) {
-		$user_id = bp_loggedin_user_id();
-	}
+	$activity = '';
 
-	$activity = bp_get_user_meta( $user_id, 'last_activity', true );
+	$last_activity = BP_Core_User::get_last_activity( $user_id );
+	if ( ! empty( $last_activity[ $user_id ] ) ) {
+		$activity = $last_activity[ $user_id ]['date_recorded'];
+	}
 
 	return apply_filters( 'bp_get_user_last_activity', $activity, $user_id );
 }
@@ -996,8 +1064,8 @@ add_filter( 'authenticate', 'bp_core_boot_spammer', 30 );
  */
 function bp_core_remove_data( $user_id ) {
 
-	// Remove usermeta
-	bp_delete_user_meta( $user_id, 'last_activity' );
+	// Remove last_activity data
+	BP_Core_User::delete_last_activity( $user_id );
 
 	// Flush the cache to remove the user from all cached objects
 	wp_cache_flush();
diff --git bp-members/bp-members-loader.php bp-members/bp-members-loader.php
index c654240..d88380b 100644
--- bp-members/bp-members-loader.php
+++ bp-members/bp-members-loader.php
@@ -72,6 +72,9 @@ class BP_Members_Component extends BP_Component {
 			'slug'          => BP_MEMBERS_SLUG,
 			'root_slug'     => isset( $bp->pages->members->slug ) ? $bp->pages->members->slug : BP_MEMBERS_SLUG,
 			'has_directory' => true,
+			'global_tables' => array(
+				'table_name_last_activity' => bp_core_get_table_prefix() . 'bp_activity',
+			),
 			'search_string' => __( 'Search Members...', 'buddypress' ),
 		) );
 
diff --git tests/includes/testcase.php tests/includes/testcase.php
index 3424efa..425f633 100644
--- tests/includes/testcase.php
+++ tests/includes/testcase.php
@@ -212,7 +212,7 @@ class BP_UnitTestCase extends WP_UnitTestCase {
 	function create_user( $args = array() ) {
 		$r = wp_parse_args( $args, array(
 			'role' => 'subscriber',
-			'last_activity' => bp_core_current_time() - 60*60*24*365,
+			'last_activity' => date( 'Y-m-d h:i:s', strtotime( bp_core_current_time() ) - 60*60*24*365 ),
 		) );
 
 		$last_activity = $r['last_activity'];
diff --git tests/testcases/core/class-bp-core-user.php tests/testcases/core/class-bp-core-user.php
index 61ca70b..7feb62c 100644
--- tests/testcases/core/class-bp-core-user.php
+++ tests/testcases/core/class-bp-core-user.php
@@ -2,6 +2,7 @@
 
 /**
  * @group core
+ * @group BP_Core_User
  */
 class BP_Tests_BP_Core_User_TestCases extends BP_UnitTestCase {
 	protected $old_current_user = 0;
@@ -119,6 +120,55 @@ class BP_Tests_BP_Core_User_TestCases extends BP_UnitTestCase {
 		$this->assertEquals( array( $u1, $u3 ), $user_ids );
 	}
 
+	/**
+	 * @group last_activity
+	 */
+	public function test_get_last_activity() {
+		$u = $this->create_user();
+		$time = bp_core_current_time();
+
+		BP_Core_User::update_last_activity( $u, $time );
+
+		$a = BP_Core_User::get_last_activity( $u );
+		$found = isset( $a[ $u ]['date_recorded'] ) ? $a[ $u ]['date_recorded'] : '';
+
+		$this->assertEquals( $time, $found );
+	}
 
+	/**
+	 * @group last_activity
+	 */
+	public function test_update_last_activity() {
+		$u = $this->create_user();
+		$time = bp_core_current_time();
+		$time2 = '1968-12-25 01:23:45';
+
+		BP_Core_User::update_last_activity( $u, $time );
+		$a = BP_Core_User::get_last_activity( $u );
+		$found = isset( $a[ $u ]['date_recorded'] ) ? $a[ $u ]['date_recorded'] : '';
+		$this->assertEquals( $time, $found );
+
+		BP_Core_User::update_last_activity( $u, $time2 );
+		$a = BP_Core_User::get_last_activity( $u );
+		$found = isset( $a[ $u ]['date_recorded'] ) ? $a[ $u ]['date_recorded'] : '';
+		$this->assertEquals( $time2, $found );
+	}
 
+	/**
+	 * @group last_activity
+	 */
+	public function test_delete_last_activity() {
+		$u = $this->create_user();
+		$time = bp_core_current_time();
+
+		BP_Core_User::update_last_activity( $u, $time );
+		$a = BP_Core_User::get_last_activity( $u );
+		$found = isset( $a[ $u ]['date_recorded'] ) ? $a[ $u ]['date_recorded'] : '';
+		$this->assertEquals( $time, $found );
+
+		BP_Core_User::delete_last_activity( $u );
+		$a = BP_Core_User::get_last_activity( $u );
+		$found = isset( $a[ $u ]['date_recorded'] ) ? $a[ $u ]['date_recorded'] : '';
+		$this->assertEquals( '', $found );
+	}
 }
